JavaScript 正弦波

2024-02-04

track : function(x, y, top, ampl) {
        return {
            top : top + 2,
            x   : x + ampl * Math.sin(top / 20),
            y   : (top / this.screenHeight < 0.65) ? y + 2 : 1 + y + ampl * Math.cos(top / 25)
        };
    }

这个程序让雪花以正弦波的方式飞舞。

但它是如何做到的呢?请解释。

It uses Math.sin for x; and Math.cos for y,但我见过的其他片段以相反的方式使用它们。为什么?到底为什么top/20 and top/25?

整个代码:

<script type="text/javascript">
var snowflakes = { // Namespace
    /* Settings */

    pics : [

        ['snow.gif' , 24, 24],
        ['snow2.gif', 24, 24],
        ['snow3.gif', 24, 24]
    ],

    track : function(x, y, top, ampl) {
        return {
            top : top + 2,
            x   : x + ampl * Math.sin(top / 20),
            y   : (top / this.screenHeight < 0.65) ? y + 2 : 1 + y + ampl * Math.cos(top / 25)
        };
    },

    quantity : 30,

    minSpeed : 20, // 1 - 100, minSpeed <= maxSpeed

    maxSpeed : 40, // 1 - 100, maxSpeed >= minSpeed

    isMelt : true, // true OR false
    /* Properties */
    screenWidth : 0,
    screenHeight : 0,
    archive : [],
    timer : null,
    /* Methods */
    addHandler : function(object, event, handler, useCapture) {
        if (object.addEventListener) object.addEventListener(event, handler, useCapture);
        else if (object.attachEvent)object.attachEvent('on' + event, handler);
        else object['on' + event] = handler;
    },
    create : function(o, index) {
        var rand = Math.random();
        this.timer = null;
        this.o = o;
        this.index = index;
        this.ampl = 3 + 7*rand;
        this.type =  Math.round((o.pics.length - 1) * rand);
        this.width = o.pics[this.type][1];
        this.height = o.pics[this.type][2];
        this.speed = o.minSpeed + (o.maxSpeed - o.minSpeed) * rand;
        this.speed = 1000 / this.speed;
        this.deviation = o.maxDeviation * rand;
        this.x = o.screenWidth * rand - this.width;
        this.y = 0 - this.height;
        this.top = this.y;
        this.img = document.createElement('img');
        this.img.src = o.pics[this.type][0];
        this.img.style.top = this.y + 'px';
        this.img.style.position = 'absolute';
        this.img.style.zIndex = 10000;
        this.img.style.left = this.x + 'px';
        this.img.obj = this;
        if (o.isMelt) this.img.onmouseover = function() {
            clearTimeout(this.obj.timer);
            this.obj.timer = null;
            this.parentNode.removeChild(this);
        }
        document.body.appendChild(this.img);
        this.move();
    },
    init : function() {
        this.screenWidth = window.innerWidth ? window.innerWidth : (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.offsetWidth);
        this.screenWidth = navigator.userAgent.toLowerCase().indexOf('gecko') == -1 ? this.screenWidth : document.body.offsetWidth;
        this.screenHeight = window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight);
        this.screenScroll = (window.scrollY) ? window.scrollY : document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
        this.archive[this.archive.length] = new this.create(this, this.archive.length);
        clearTimeout(this.timer);
        this.timer = null
        this.timer = setTimeout(function(){snowflakes.init()}, 60000 / this.quantity);
    }
};
snowflakes.create.prototype = {
    move : function() {
        var newXY = this.o.track(this.x, this.y, this.top, this.ampl);
        this.x   = newXY.x;
        this.y   = newXY.y;
        this.top = newXY.top;
        if (this.y < this.o.screenHeight + this.o.screenScroll - this.height) {
            this.img.style.top  = this.y + 'px';
            this.x = this.x < this.o.screenWidth - this.width ? this.x : this.o.screenWidth - this.width;
            this.img.style.left = this.x + 'px';
            var index = this.index;
            this.timer = setTimeout(function(){snowflakes.archive[index].move()}, this.speed);
        } else {
            delete(this.o.archive[this.index]);
            this.img.parentNode.removeChild(this.img);
        }
    }
};
snowflakes.addHandler(window, 'load', function() {snowflakes.init();});
snowflakes.addHandler(window, 'resize', function() {snowflakes.init();});
    </script>

基本正弦函数定义为:

f(x) = A sin(wt + p)

where

  • A是振幅
  • w 是频率
  • p 是相位

这些因素决定了 f 的图形的外观。

幅度可以被认为是一个比例因子,A 越大,f 的峰值和低值(绝对值)就越大。

频率决定了正弦函数运行其所有值直到重新开始的速度 - 正弦是一个周期函数。 k 越大,f 运行一个周期的速度就越快。

p 是相位,可以将其视为将函数的起点向右(正 p)或向左(负)“移动”。很难用言语解释,看看here http://www.algebralab.org/lessons/lesson.aspx?file=trigonometry_trigperiodfreq.xml对于图表。

您在示例中给出的函数是通用版本

f: R->R², f(t)=(sin(t), cos(t))

这是(之一)单位圆的参数化 http://colalg.math.csusb.edu/~devel/precalcdemo/param/src/param.html。如果单调增加 t 并绘制 x (sin(t)) 和 y (cos(t)),您将得到一个在半径为 1 的圆上飞行的点。

你的广义函数是

f: R->R², f(t) = (A sin(1/wt), A cos(1/wt)), w > 1

在您的情况下,A=ampl,t=top,x 坐标为 w=20,y 坐标为 w=25。 w 的这些轻微偏差使运动变得不稳定,因此它不再是一个完美的圆形,而是一些“扭曲”的椭圆形 - 我猜雪花不会以完美的圆形落下。此外,这使得薄片的路径看起来比直的完美圆更加随机。但这只是一种幻觉,这一切都是确定性的并且仍然是周期性的 - 只是 x 和 y 运动“异相”,因此需要更长的时间才能完成一个周期。

选择 w > 1 以“减慢”圆周运动。你选择的w越大,频率就越低,你的移动点完成一整圈的速度就会慢得多。

你选择的A越大,你的圈子就会变得越大。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript 正弦波 的相关文章

随机推荐

  • 未定义的参考问题

    当我尝试编译这个时 include OriAudioCache hpp int main System audioSystem 0 FMOD RESULT result result System Create audioSystem FM
  • 线程堆栈指针

    在Linux 2 6 32 32中 有没有一种方法可以在a中以编程方式查找有关线程的以下信息pthreads程序 我需要 运行计数 堆栈指针 堆栈开始 结束 堆栈大小 堆栈使用情况 我猜是类似 ThreadX 的东西 但在程序中 谢谢 pt
  • Python 2.7:在Windows控制台中输出utf-8

    比方说 s u test u0627 u0644 u0644 u0647 u0623 u0643 u0628 u0631 u7206 u767A u043E u043B u043E u043B u043E 如果我尝试直接打印它 gt gt
  • Javascript 中的数组左旋转将记录到控制台但不返回

    我正在 Hackerrank 上研究数组左旋转 我的解决方案将 console log 包含正确结果的数组 但无法使用 return 来工作 这是他们网站上的详细信息 打印一行 n 个空格分隔的整数 表示执行 d 次左旋转后数组的最终状态
  • Visual Studio 使用查找/替换和结束行正则表达式 ($) 将文本附加到行尾

    我尝试使用 Visual Studio 或 SQL Server Management Studio 在查找 替换对话框中使用以下设置将一些文本 例如 Fish 附加到文件中每一行的末尾 查找内容 替换为 鱼 使用正则表达式 选中 这主要完
  • 从视图运行自定义管理命令

    我有一个自定义管理命令 可以通过电子邮件发送报告 它通常从 cron 作业运行 我想做的是向我的网络应用程序添加一个按钮 单击该按钮将导致管理命令在那里运行 然后而不是等待 cron 作业调用它 我该怎么做呢 我是否必须调用命令行 例如 p
  • Parse.com 是否可以使用 facebook 登录,同时检查 facebook 用户的电子邮件是否存在于解析中的用户中以及是否链接两者?

    我在解析 iOS SDK 时遇到以下问题 在我的应用程序中 用户可以使用电子邮件 用户名 密码或 Facebook 登录 当他们使用 Facebook 时 电子邮件 用户名 会自动设置 但是 如果用户首先使用电子邮件 密码登录 然后在注销后
  • mysql 语法 in 子句

    我正在使用 mysql 想知道它的语法 我想创建一个像这样的 IN 子句 from id OR to id IN 但我不知道语法是怎样的 我想避免像这样运行 in 子句两次 from id IN OR to id IN 最好的问候 亚历山大
  • 菜单和下拉菜单之间的空间

    我希望下拉菜单显示在主菜单区域的边框线下方 而不是显示在 菜单 标题 按钮的正下方 我可以更改位置 使其更低 但中间存在死区 导致无法将鼠标悬停在下拉菜单上 我不想在下拉菜单上方添加填充 因为这只会创建更多的紫色空间 我希望该空间为空 下面
  • C++ 如何将参数隐式转换为比较器,例如 <?

    我原以为这将是一个通过谷歌解决的简单问题 但我似乎找不到明确的 甚至是推测性的 答案 使用比较器语句时 隐式转换按什么顺序发生 int i 1 size t t 1 bool result i lt t 这是否相当于 bool result
  • 同一表达式中多个参数包的多次展开

    我想问一下下面的代码是否有效 我想知道是否有可能在一个表达式中多次扩展参数包 include
  • 自动调整 UITableViewCell 的两列大小

    我有一个 UITableViewCell 其中有两列 每列都是一个 UILabel 每个标签都是多行 numberOfLines 0 我想要的是根据较高的标签来垂直调整表格视图单元格的大小 我为每个标签的左右和顶部设置了约束 但我不确定如何
  • 基本简单 Asp.net + jQuery + JSON 示例

    我正在尝试学习如何从 Javascript jQuery 对服务器进行简单的调用 我一直在努力学习 但找不到包含这些简单步骤的教程 我想用两个参数 一个日期时间和一个字符串 向服务器发送一条消息并返回一个日期时间 我想通过 JSON 来做到
  • Win32 安装程序:有没有办法为每个用户写入 HKU 启动?

    是否有一个 Windows 安装程序可以为每个用户添加启动项 例如
  • Android自定义圆形ProgressBar方向

    我有一个自定义的圆形进度条 这是我确定的可绘制对象
  • 如何让这个java动画流畅呢?

    我需要用我的框架及其内部面板进行动画运动 当用户单击特定的内部面板 框架内部的面板 时 另一个面板将添加到框架的contentPane然后框架和新面板的宽度都会增加 但我总是希望我的框架位于屏幕中间 我用这种方式解决了动画 Containe
  • 摆脱WPF中的按钮边框?

    i am trying to get rid of button border and only display text however a thin line around the text gets displayed even th
  • 如何从下拉列表中传递选定的值并将其作为 Rails 中级联下拉列表的参数进行访问

    Edited 我正在尝试实现级联下拉菜单 在我的第一个下拉列表中 我得到了所有不同的名称 选择名称时 如何访问该值并将其传递给控制器 模型 以便我可以根据值进行过滤并将其绑定到下一个下拉列表 在我的模型中 我有以下范围 scope dist
  • 仅使用辅助全局索引查询 Dynamodb 表

    我尝试使用辅助全局索引查询 Dynamodb 表 但收到 java lang IllegalArgumentException 非法查询表达式 在查询中找不到哈希键条件 我想做的就是获取时间戳大于某个值的所有项目 而不考虑密钥 时间戳不是键
  • JavaScript 正弦波

    track function x y top ampl return top top 2 x x ampl Math sin top 20 y top this screenHeight lt 0 65 y 2 1 y ampl Math