2011-01-11 142 views
0

我有3个粒子,其中一个是中心粒子。我想通过公式q'=Θq+ p旋转其他两个粒子(存储在粒子列表中),其中q'是旋转粒子的新位置,θ是方向角,p是中心粒子。其他两个粒子的初始位置存储在initialParticlePosition列表中。问题是我认为我计算的角度是错误的,因为范围。我应该把范围作为[-pi,pi)或类似的东西。在某些部分它计算正确,但有时它是错误的。有人可以帮助我使用这个代码或给我另一种旋转方法。c#旋转问题

{ 

     angle = Math.Acos(Vector2.Dot(heading,new Vector2(0,-1))); 

     for (int i = 0; i < 2; i++) 
     { 
      tempX = (double)initialParticlePositions[i].X * Math.Cos(angle) - (double)initialParticlePositions[i].Y * Math.Sin(angle) + centerParticle.position.x; 
      tempY = (double)initialParticlePositions[i].X * Math.Sin(angle) + (double)initialParticlePositions[i].Y * Math.Cos(angle) + centerParticle.position.y; 
      particles[i].position.x = tempX; 
      particles[i].position.y = tempY; 
     } 
} 
+0

用已知的角度值运行代码并在纸上绘制输出**。手动验证输出。 `cos`和`sin`应该处理[`-pi,pi]`之外的角度(自从我做这种事情已经有一段时间了)。 – ChrisF 2011-01-11 20:06:09

回答

0
angle = Math.Acos(Vector2.Dot(heading,new Vector2(0,-1))); 

当你怀疑,你的点积和反余弦只会给你一个180度 范围的角度组合。

取而代之,使用单位矢量上的Atan2来获取从-pi到pi的全方位角度。

angle = (float)Math.Atan2((double)heading.Y, (double)heading.X); 

如果您的Y轴在向下方向为正,您可能需要否定Y项。

2

一些方法,可以帮助(角度总是度,而不是弧度):

public static double GetAngle(Vector v) 
    { 
     return Math.Atan2(v.X, -v.Y) * 180.0/Math.PI; 
    } 

    public static Vector SetAngle(Vector v, double angle) 
    { 
     var angleInRads = angle * (Math.PI/180.0); 
     var distance = v.Length; 
     v.X = (Math.Sin(angleInRads) * distance); 
     v.Y = -(Math.Cos(angleInRads) * distance); 
     return v; 
    } 

    static public Point RotatePointAroundCenter(Point point, Point center, double rotationChange) 
    { 
     Vector centerToPoint = point - center; 
     double angle = GetAngle(centerToPoint); 
     Vector centerToNewPoint = SetAngle(centerToPoint, angle + rotationChange); 
     return center + centerToNewPoint; 
    } 

(你应该开始标记的答案,帮助为答案,点击左侧下方的票对号大纲,例如你可以接受this answer

编辑:优化了方法一下。

+1

+1 ...你可能会提供你正在做什么的解释。具体而言,您正在翻译该点,以便它与原点相关,进行旋转,然后翻译回去。 – 2011-01-11 20:27:37

1

被绕粒子位置可以与每个代码单个线来设置:

假定P1,P2,P3 &被Vector2s和p2 & P3的轨道P1。

p2 = Vector2.Transform(p2 - p1, Matrix.CreateRotationZ(rotationChangeP2)) + p1; 

p3 = Vector2.Transform(p3 - p1, Matrix.CreateRotationZ(rotationChangeP3)) + p1; 

Matrix.Create ...()方法将为您调用两个trig函数。

编辑。矩阵& Vector2结构&方法是XNA特定的,但包括在这里,因为这是OP标记他的Q。