javascript-旋转正弦曲线

我正在使用以下公式绘制正弦曲线,

this.x += this.speed
this.y = this.amp * Math.sin( this.x * this.cycles ) + this.center

我通过在每帧上绘制小圆圈来点画点.这样可以实现从左到右绘制的正弦曲线.但是,如果我想旋转此曲线以使其随机绘制360度,该如何修改代码?再说一遍,有时我希望曲线从左到右是相同的图,有时我希望曲线向下成45度,有时是向后等.

解决方法:

一种选择是计算笛卡尔坐标中的点,转换为极点,添加角度偏移,然后再次转换回笛卡尔坐标.

this.x += this.speed
this.y = this.amp * Math.sin( this.x * this.cycles ) + this.center

this.r = Math.sqrt(this.x * this.x + this.y * this.y);
this.a = Math.atan2(this.y, this.x);

this.a += rotation_angle;

this.x = this.r * Math.cos(this.a);
this.y = this.r * Math.sin(this.a);

这会将数学库调用的次数从一增加到五,因此我希望它的速度大约是原始计算的五分之一.这可能会或可能不会.实际上,我们可以使用三角恒等式sin(ab)= sin(a)cos(b)cos(a)sin(b)和cos(ab)= cos(a)cos(b)-sin(a (b)身份.

对于旋转的X坐标:

  this.r * cos(this.a)
= this.r * cos(atan2(this.y, this.x) + rotation)
= this.r * (cos(atan2(this.y, this.x))cos(rotation) - sin(atan2(this.y, this.x))sin(rotation))
= this.r * ((this.x / this.r)cos(rotation) - (this.y / this.r)sin(rotation))
= this.x * cos(rotation) - this.y * sin(rotation)

对于旋转的Y坐标:

  this.r * sin(this.a)
= this.r * sin(atan2(this.y, this.x) + rotation)
= this.r * (sin(atan2(this.y, this.x))cos(rotation) + cos(atan2(this.y, this.x))sin(rotation))
= this.r * ((this.y / this.r)cos(rotation) + (this.x / this.r)sin(rotation))
= this.y * cos(rotation) + this.x * sin(rotation)

我们的新代码如下所示:

x = this.x + this.speed
y = this.amp * Math.sin( x * this.cycles ) + this.center

this.x = x * cos(rotation_angle) - y * sin(rotation_angle);
this.y = y * cos(rotation_angle) + x * sin(rotation_angle);

我们引入了变量x和y,因为我们需要它们的原始形式来计算this.x和this.y中的每一个.我们不再需要在极坐标中工作,因为我们的身份使我们能够消除这些中间步骤.另外,如果rotation_angle为常数,则可以预先计算;否则,您可以将调用保留在每个点的计算中,并获得螺旋型效果.

如果您不想完全使用角度,则可以通过使用参数定义x = f(t)和y = g(t)定义一条曲线,确定每个点t的垂直线来使用任意函数进行工作-通过分析地找到f'(t)和g'(t)并对其进行编码-或通过在关注点附近对其进行数值近似.然后,您只需沿该指向法线的位移绘制一个点,该点等于您当前为此this.y计算的值.因此,如果您想沿着抛物线绘制正弦曲线,则可以执行以下操作:

t += speed;
r = this.amp * Math.sin(t * this.cycles) + this.center;

x = t;
y = t * t;

dxdt = 1;
dydt = 2t;
dydx = dydt / dxdt;
if (-epsilon <= dydt && dydt <= epsilon) {
    this.x = x;
    this.y = y + r;
} else {
    normal = -1.0 / dydx;
    this.x = x + r * ( 1.0 / Math.sqrt(1 + dydx * dydx));
    this.y = y + r * (dydx / Math.sqrt(1 + dydx * dydx));
}

我没有尝试运行它,所以它可能会有一些错误,但是从理论上讲这些错误应该是可修复的,这样您才能获得预期的效果:正弦曲线围绕(定向!)抛物线y = x ^ 2定向为从从负到正x.

上一篇:在Python中拟合分箱的对数正态数据


下一篇:python – Scipy的curve_fit没有给出合理的结果