проблема вращения c # - PullRequest
0 голосов
/ 11 января 2011

У меня есть 3 частицы, и одна из них является центральной частицей. Я хочу повернуть две другие частицы (сохраненные в списке частиц) относительно центральной частицы с формулой q '= Θq + p, где q' - это новая позиция повернутой частицы, Θ - это угол ориентации, а p - это положение центральная частица. Начальная позиция двух других частиц сохраняется в списке initialParticlePosition. Проблема в том, что я считаю, что угол, который я вычисляю, неверен из-за диапазона. Мне кажется, я должен принять диапазон как [-pi, pi) или что-то вроде этого. В некоторых частях это вычисляет правильно, но иногда это неправильно. Может ли кто-нибудь помочь мне с этим кодом или дать мне другой метод поворота.

{

         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;
         }
}

Ответы [ 3 ]

2 голосов
/ 11 января 2011

Некоторые методы, которые могут помочь (углы всегда в градусах, а не в градусах):

    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;
    }

(Вы должны начать отмечать ответы, которые помогают в качестве ответа, щелкните контур галочки под голосами слева, напримерВы можете принять этот ответ )

Редактировать: Немного оптимизировать методы.

1 голос
/ 12 января 2011

Позиции частиц, которые находятся на орбите, можно задать одной строкой кода каждая:

Предположим, что 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 ... () вызовет для вас две триггерные функции.

редактировать. структуры и методы Matrix & Vector2 специфичны для XNA, но включены сюда, потому что это то, с чем ОП пометил свой Q.

0 голосов
/ 12 января 2011
angle = Math.Acos(Vector2.Dot(heading,new Vector2(0,-1)));

Как вы подозреваете, ваша комбинация точечного произведения и Acos даст вам углы только в диапазоне 180 градусов.

Вместо этого используйте Atan2 на вашем единичном векторе, чтобы получить полный диапазон углов от-pi к пи.

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

Вам может потребоваться отменить член Y, если ваша ось Y положительна в направлении вниз.

...