Quaternion Rotationsspiegel oder Flips manchmal C#C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Quaternion Rotationsspiegel oder Flips manchmal C#

Post by Anonymous »

Ich habe meine eigene Klasse in C# von Quaternions implementiert, um zu verstehen, wie 3D -Objekte auf Computerbildschirmen angezeigt werden. Das hat wirklich gut funktioniert, aber wenn ich versuche, alle Punkte eines Objekts über 90 Grad (oder einem Vielfachen davon) zu drehen, kehrt es manchmal (nicht immer) die Rotation um oder dreht das Objekt in der Forthdimension (ich bin nicht schüre, was nicht wahr ist, weil ich ein symetrisches Objekt geladen habe. Aufaussetzung: Ich habe es mit einfachem Koordinaten ausprobiert. ist drastisch reduziert, wenn ich die Achse, die von oben nach unten des Bildschirms verläuft, nicht verwende oder zuerst eine andere Achse dreht). Ich habe mir die Quaternion angesehen, die ich auf alle Punkte und in beiden Fällen applaye (umgedreht und nicht umdrehen).

Code: Select all

public void rotateq(Vector3 rotationAxisNew, float angleNew, GameTime time)
{
if (angleNew == 0)
return;
angleNew = angleNew * time.DeltaTime * Loop.Scale_FPS;
/*CreateRotationQuaternionFromAxisAngle:
This method creates a quaternion that represents a rotation around an axis with a specific angle. It takes the vector of the rotation axis and the angle as input parameters.  The vector of the axis is normalized to ensure that it has a length of 1.
Quaternion multiplication:
The quaternions are multiplied together to produce the resulting rotation.
Resulting quaternion:
The resulting quaternion represents the combined rotation.*/
Quanternion rotationAxisNewQ = Quanternion.CreateRotationQuaternionFromAxisAngle(rotationAxisNew, angleNew*100);
rotationAxisNewQ.normalisieren();
this.rotationAxis = this.rotationAxis * rotationAxisNewQ;
this.rotationAxis.normalisieren();
Console.WriteLine(rotationAxis);
lastTimeTheSame = false;
}
< /code>
Dann gibt es meine Klasse von Quaternions, die ich in Quanternions < /p>
umbenannteusing SFML.System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
using System.Data.Entity.Core.Mapping;
namespace SMFL_Test
{
public class Quanternion
{
public float w { get; set; }
public float i { get; set; }
public float j { get; set; }
public float k { get; set; }
public float length;

public Quanternion(float w, float i, float j, float k)
{
//W
this.w = w;
//X
this.i = i;
//Y
this.j = j;
//Z
this.k = k;
length = (float)Math.Sqrt(betrag());
}
public Quanternion(float w, Vector3f hi)
{
this.w = w;
this.i = hi.X;
this.j = hi.Y;
this.k = hi.Z;
length = (float)Math.Sqrt(betrag());
}
public Quanternion(float w, Vector3 hi)
{
this.w = w;
this.i = hi.X;
this.j = hi.Y;
this.k = hi.Z;
length = (float)Math.Sqrt(betrag());
}
public Quanternion(Quanternion hi)
{
//W
this.w = hi.w;
//X
this.i = hi.i;
//Y
this.j = hi.j;
//Z
this.k = hi.k;
length = (float)Math.Sqrt(betrag());
}
public static bool operator ==(Quanternion a, Quanternion b)
{
return (a.w == b.w && a.i == b.i && a.j == b.j && a.k == b.k);
}
public static bool operator !=(Quanternion a, Quanternion b)
{
return !(a.w == b.w && a.i == b.i && a.j == b.j &&  a.k == b.k);
}
public static Quanternion operator *(Quanternion a,Quanternion b)
{

return new Quanternion(
a.w*b.w - a.i*b.i - a.j*b.j - a.k*b.k,
a.w*b.i + a.i*b.w + a.j*b.k - a.k*b.j,
a.w*b.j - a.i*b.k + a.j*b.w + a.k*b.i,
a.w*b.k + a.i*b.j - a.j*b.i + a.k*b.w
);
}
public static Quanternion operator *(Quanternion a, float b)
{
return new Quanternion(a.w * b, a.i * b, a.j * b, a.k * b);
}
public static Quanternion operator *(float b, Quanternion a)
{
return new Quanternion(a.w * b, a.i * b, a.j * b, a.k * b);
}
public static Quanternion operator +(Quanternion a, Quanternion b)
{
return new Quanternion(b.w + a.w, b.i + a.i,b.j + a.j, b.k + a.k);
}
public static Quanternion operator /(Quanternion a, Quanternion b)
{

return a * b.multiplikativeInverse();
}
public static Quanternion operator /(Quanternion a, float b)
{
return new Quanternion(a.w / b, a.i / b, a.j / b, a.k / b);
}
public static Quanternion operator -(Quanternion a, Quanternion b)
{
return new Quanternion(a.w - b.w, a.i - b.i, a.j - b.j, a.k - b.k);
}
public static Quanternion operator -(Quanternion a)
{
return new Quanternion(-a.w, -a.i, -a.j, -a.k);
}
public float betrag()
{
return (float)Math.Sqrt(w*w+i*i+j*j+k*k);
}
public Quanternion conjugate()
{
return (new Quanternion(w, -i, -j, -k));
}
public Quanternion multiplikativeInverse()
{
float absolutSquared = this.absolut();
absolutSquared *= absolutSquared;
return ( new Quanternion(
this.w / absolutSquared,
-this.i / absolutSquared,
-this.j / absolutSquared,
-this.k / absolutSquared));
}
public void normalise()
{
if(length != 1)
{
w = w / length;
this.i = this.i / length;
j = j / length;
k = k / length;
length = (float)Math.Sqrt(absolut());
}
}
public Quanternion normalVektor()
{
return new Quanternion(w/length,i/length,j/length,k/length);
}
public override string ToString()
{

return "w: "+w+" i: "+i+" j: "+j+"  k: "+k;
}
public Vector3f convertToVector3f()
{
return new Vector3f((float)i, (float)j, (float)k);
}
public Vector3 convertToVector3()
{
return new Vector3((float)i, (float)j, (float)k);
}
public Quanternion Clone()
{
return new Quanternion(this.w,this.i,this.j,this.k);
}
public float skalar(Quanternion test)
{
return this.w * test.w + this.i * test.i + this.j * test.j + this.k * test.k;
}
public static Quanternion CreateRotationQuaternionFromAxisAngle(Vector3 axis, float angle)
{
// axis must be a unit vector, so we normalize it
//axis = new Vector3(0, 1, 0);
axis = axis/axis.Length();
float halfAngle = (float)Math.PI / 360 * angle;
float sinHalfAngle = (float)Math.Sin(halfAngle);
float cosHalfAngle = (float)Math.Cos(halfAngle);
// create Quaternion : q = cos(θ/2) + (sin(θ/2) * x, y, z)
return new Quanternion(cosHalfAngle, -axis.X * sinHalfAngle, -axis.Y * sinHalfAngle, -axis.Z * sinHalfAngle);
}
}
}
< /code>
Und so drehe ich die Punkte: < /p>
private void rotateqRotation(float offsetX,float offsetY,float offsetZ)
{
double absolut = rotationAxis.absolut();
if (betrag == 0)
return;
//Since the rotation quantum ion is stored, we do not need to change the rotation axis
//With Parrallel we can parrallelize the whole thing
Parallel.ForEach(Edges3D, edge =>
{
Quanternion point0Result = new Quanternion(0, Vertecies3D[edge[0]].X-midpoint.X, Vertecies3D[edge[0]].Y-midpoint.Y, Vertecies3D[edge[0]].Z- midpoint.Z);
Quanternion point1Result = new Quanternion(0, Vertecies3D[edge[1]].X-midpoint.X, Vertecies3D[edge[1]].Y-midpoint.Y, Vertecies3D[edge[1]].Z-midpoint.Z);

point0Result = rotationAxis * point0Result * rotationAxis.conjugated();
point1Result = rotationAxis * point1Result * rotationAxis.conjugated();

Vertecies3DCopy[edge[1]] = point1Result.convertToVector3();
Vertecies3DCopy[edge[0]] = point0Result.convertToVector3();
});
rotation[0] = new Vertex(new Vector2f(offsetX, offsetY), Color.Red);
rotation[1] = new Vertex(new Vector2f(offsetX, offsetY), Color.Red);
}
< /code>
Und so habe ich die Punkte gespeichert: < /p>
private List Vertecies3D = new List();
private List Vertecies3DCopy;
//Add only lists with 2 entries!!!:
private List Edges3D = new List();
//Add only lists with 3 entries!!!:
private List Surfaces3D = new List();
//Initialization with the identity rotation quarternion
//Unfortunately, I have not been able to find out why the rotation is reversed
private Quanternion rotationAxis = new Quanternion(1, 0, 0, 0);
private Vector3 rotationAxisRaw = new Vector3(0,0,0);
private Vector3 rotationAxisKamera = new Vector3(0, 0, 0);
private bool lastTimeTheSame = false;
private bool lastKameraTheSame = false;

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post