Ограничения угла соединения Ragdoll
Я делаю проект C# для ragdolls, основанный на статье Томаса Якобсена http://www.gpgstudy.com/gpgiki/GDC%202001%3A%20Advanced%20Character%20Physics
Я преобразовал логику в 2D, и все, кажется, работает, только у меня проблемы с реализацией угловых ограничений.
Это код, который я использую в данный момент:
public static void SatisfyAngleConstraint(Particle p1, Particle p, float minAngle, float maxAngle)
{
float a1 = (float)Math.Atan2(p1.m_x.X - p1.getFixPoint().X, p1.m_x.Y - p1.getFixPoint().Y);
float a2 = (float)Math.Atan2(p.m_x.X - p.getFixPoint().X, p.m_x.Y - p.getFixPoint().Y);
float diffAngle = a2 - a1;
Game.currentGame.Window.Title = "a " + diffAngle;
//Vector2 OldPosition = p.m_x;
if (diffAngle > maxAngle)
p.m_x = RotatePoint(p.m_x, p.getFixPoint(), (diffAngle - maxAngle));
else if (diffAngle < minAngle)
p.m_x = RotatePoint(p.m_x, p.getFixPoint(), (diffAngle - minAngle));
//p.m_oldx += p.m_x - OldPosition;
}
Частицы p1 и p являются соединениями, а getFixPoint() возвращает положение родительского соединения. RotatePoint(точка, centerPoint, angleRad) возвращает положение точки, повернутой вокруг centerPoint радианами angleRad.
Этот код вызывает сильные дрожания и из-за того, что я использую интеграцию Verlet - я пытался компенсировать это, добавляя преобразование и к старой позиции, и это, кажется, решает некоторые из моих проблем, но я все еще испытываю серьезные дрожания и случайное применение силы, которое заставляет меня поверить, что моя математика плохая.
Я применяю это ограничение после ограничения расстояния, потому что расстояние между соединениями должно быть постоянным, когда я вращаюсь вокруг родительского соединения.
Это мой первый вопрос, связанный с переполнением стека, поэтому, пожалуйста, сообщите мне, если моя форма плохая.
1 ответ
Я обнаружил, что корень моей проблемы заключается в способе вычисления углов между векторами. Очень хорошее решение этой проблемы можно найти здесь: /questions/35263738/ispolzovanie-atan2-dlya-nahozhdeniya-ugla-mezhdu-dvumya-vektorami/35263749#35263749
Использование этого метода для вычисления a1 и a2 избавляет от дрожания. Проблема всего этого подхода заключается в том, что verlet применяет линейную силу к конфликтующему соединению, но вы хотите, чтобы сила передавалась вращением на родительское соединение (обратная кинематика))
Поэтому я бы рекомендовал другой подход к 2D тряпичным куклам с ограничениями по углу.