c# rotation problem
I have 3 particles and one of them is the center particle. I want to rotate other two particle ( stored in particles list ) relative to the center particle with the formula q' = Θq + p where q' is the new position of the rotated particle, Θ is the orientation angle and p is the position of center particle. The initial position of other two particles is stored in initialParticlePosition list. THe problem is I think the angle I calculate is wrong because of the range. I thing I should take the range as [-pi, pi) or something like this. In some parts it calculates correct but sometimes it is wrong. Can someone help me with this code or give me another method of rotating.
{
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;
}
}
开发者_运维问答
Some methods that might help (angles always in degrees, not rad):
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;
}
(You should start marking answers that help as answer, click the checkmark outline below the votes on the left, e.g. you could accept this answer)
Edit: Optimized the methods a bit.
The particle positions that are orbiting can be set with a single line of code each:
Assume p1, p2, & p3 are Vector2s and p2 & p3 are orbiting p1.
p2 = Vector2.Transform(p2 - p1, Matrix.CreateRotationZ(rotationChangeP2)) + p1;
p3 = Vector2.Transform(p3 - p1, Matrix.CreateRotationZ(rotationChangeP3)) + p1;
The Matrix.Create...() method will call the two trig functions for you.
edit. the Matrix & Vector2 structures & methods are XNA specific but included here because that's what the OP tagged his Q with.
angle = Math.Acos(Vector2.Dot(heading,new Vector2(0,-1)));
As you suspect, your combination of dot product and Acos will only give you angles in a 180 degree range.
Instead, use Atan2 on your unit vector to get a full range of angles from -pi to pi.
angle = (float)Math.Atan2((double)heading.Y, (double)heading.X);
You may need to negate the Y term if your Y axis is positive in the down direction.
精彩评论