So beschränken Sie Gelenkrotationen im CCDC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 So beschränken Sie Gelenkrotationen im CCD

Post by Anonymous »

Ich kämpfe verzweifelt mit Mathematik, um mich zu verbessern, habe ich versucht, eine IK-Lösung in Unity zu erstellen.

Ich habe einen einfachen CCD-Algorithmus erstellt, der sich wie beabsichtigt verhält:

Aber wenn ich versuche, Einschränkungen zu den Gelenkwinkeln hinzuzufügen, ist das Verhalten ungenau und verzerrt:

Derzeit habe ich eine for-Schleife, die alle Gelenke in der Kette durchläuft, solange das Ziel nicht erreicht wird und die aktuellen Versuche < Versuchsschwellenwert sind.

Sobald die Korrekturdrehung für jedes Gelenk berechnet ist, wende ich sie auf Gelenk an.
Dann überprüfe ich die Drehung an jedem Gelenk und klemme es ein Es ist der Min-Max-Bereich.

Hier ist der Code, der die Rotation anwendet und dann die Rotationsgrenzen überprüft:

Code: Select all

Vector3 vectorCurrJointToEndEffector = (joints[joints.Length - 1].transform.position - joints[i].transform.position).normalized; //normalised vector from current joint to end effector position
Vector3 vectorCurrJointToTarget = (target.transform.position - joints[i].transform.position).normalized; //normalised vector from current joint to targetposition

float cosineAngle = Vector3.Dot(vectorCurrJointToEndEffector, vectorCurrJointToTarget); //dot product gives the cosine of the angle for the corrective rotation

//limit possibilities
if (cosineAngle < 1)
{
Vector3 crossProduct = Vector3.Cross(vectorCurrJointToEndEffector, vectorCurrJointToTarget).normalized; //normalised cross product gives the axis on which to rotate the joint

float toRotateDegrees = Mathf.Acos(cosineAngle) * Mathf.Rad2Deg; //calculate joint rotation in degrees

joints[i].transform.rotation = Quaternion.AngleAxis(toRotateDegrees, crossProduct) * joints[i].transform.rotation; //apply joint rotation

joints[i].transform.rotation = Quaternion.AngleAxis(toRotateDegrees, crossProduct) * joints[i].transform.rotation; //apply joint rotation

//clamp current joint rotation within set limits
Vector3 currentJointEulerAngles = joints[i].joint.transform.localRotation.eulerAngles;

if (currentJointEulerAngles.x > 180f)
currentJointEulerAngles.x -= 360f;
currentJointEulerAngles.x = Mathf.Clamp(currentJointEulerAngles.x, joints[i].XaxisMin, joints[i].XaxisMax);

if (currentJointEulerAngles.y > 180f)
currentJointEulerAngles.y -= 360f;
currentJointEulerAngles.y = Mathf.Clamp(currentJointEulerAngles.y, joints[i].YaxisMin, joints[i].YaxisMax);

if (currentJointEulerAngles.z > 180f)
currentJointEulerAngles.z -= 360f;
currentJointEulerAngles.z = Mathf.Clamp(currentJointEulerAngles.z, joints[i].ZaxisMin, joints[i].ZaxisMax);

joints[i].joint.transform.localEulerAngles = currentJointEulerAngles;

Wie im zweiten Video gezeigt, ist das Ergebnis sehr schlecht.

Könnte jemand eine Lösung vorschlagen und möglicherweise eine Erklärung, warum das nicht funktioniert?

Aktualisierter, korrigierter Tippfehler im eingefügten Code.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post