画布,使用正弦波沿方形路径为形状设置动画

Posted

技术标签:

【中文标题】画布,使用正弦波沿方形路径为形状设置动画【英文标题】:Canvas, animate a shape along square path using sine wave 【发布时间】:2014-06-06 15:17:39 【问题描述】:

我正在尝试根据设置的“半径”沿方形路径制作一个简单的形状动画。 Atm 我使用正弦波随着时间的推移设置位置,因此它基本上沿圆形路径设置动画。 有没有办法使用数学来改变正弦波以使动画正方形。我知道还有其他方法可以做到这一点,但我有兴趣了解它背后的数学原理。

我有一个示例小提琴:

t = new Date().getTime()

r = 25

x = (r * Math.cos t * 0.005) 
y = (r * Math.sin t * 0.005)

http://jsfiddle.net/Z5hrM/1/

【问题讨论】:

【参考方案1】:

我们可以做得比圆形或方形更好! x 和 y 的方程可以用指数 D 泛化:

 x = (r^D * cos(theta))^(1/D) and y = (r^D * sin(theta))^(1/D)

当 D = 1 时,您有熟悉的等式给出一个圆。当 D = 0.5 时,你会得到一颗钻石,当 D 1 时,你会得到越来越多的块状形状,而当 D -> infinity 时,你会得到一个正方形。 试试这个 sn-p;随着动画的进行,您可以键入新的 D 值。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>animation problem</title>
<script type='text/javascript'>
    function demo()
        var w = 400;
        var ctx = document.getElementById("canvas").getContext("2d");
        ctx.canvas.width = w;
        ctx.canvas.height = w;
        var r = w/4;
        var theta = 0;

        setInterval(function()
            ctx.canvas.width += 0;    //  clear the canvas
            ctx.translate(w/2, w/2);  //  center it on (0,0)
            var D = +document.getElementById("exponent").value;

            var xSign = Math.cos(theta) < 0 ? -1 : 1;  // Handle all quadrants this way
            var ySign = Math.sin(theta) < 0 ? -1 : 1;
            var x = xSign*Math.pow( Math.pow(r, D)*Math.abs(Math.cos(theta)), 1/D );
            var y = ySign*Math.pow( Math.pow(r, D)*Math.abs(Math.sin(theta)), 1/D );
            ctx.fillStyle = "blue";
            ctx.arc( x, y, 20, 0, 6.2832, false );
            ctx.fill();

            theta += Math.PI/100;
        , 20);
    
</script>
</head>
<body onload='demo()'>
    <input id='exponent' type=text value='1'\>
    <br />
    <canvas id='canvas'></canvas>
</body>
</html>

【讨论】:

【参考方案2】:

jsFiddle Demo

实际上不需要太多修改。考虑到余弦代表 x 坐标,而 sin 代表 y 坐标,很明显,要制作方形路径,这些值之一必须设置为整数而不是部分值。

因此,Math.cos t 和 Math.sin t 需要用一个变量和一个条件来调节

xcos = Math.cos t * 0.005
ysin = Math.sin t * 0.005

if Math.abs(xcos) > Math.abs(ysin)
 xcos = Math.round(xcos)                                       
else
 ysin = Math.round(ysin)     

x = @cx + (radius * xcos)
y = @cy + (radius * ysin)

【讨论】:

【参考方案3】:

您的变量 r 应该是两个位置 (x,y) 的向量,它们将分别处理 x 和 y 上的位置/增量。看看当你这样做时 x = (0 * Math.cos t * 0.005) 圆圈刚刚从上到下移动。为了获得形状行为,您需要随时间控制向量(x 和 y 位置)并使用余数来包装 x 和 y 位置 (%)。

问候。

【讨论】:

以上是关于画布,使用正弦波沿方形路径为形状设置动画的主要内容,如果未能解决你的问题,请参考以下文章

正弦波转变为方波?

一起Talk Android吧(第四百一十四回:使用三角函数绘制正弦波的优化)

正弦波转换为方波

在平移/缩放/旋转时,将正弦波推动通过一个几何体

如何讲正弦波转化为方波?频率不变。

利用运放怎样实现由方波变成正弦波