Entwickler-Ecke
WPF / Silverlight - Kamera um ein Objekt drehen (Kit3d-codeplex)
_Joe_ - Mi 14.01.09 17:10
Titel: Kamera um ein Objekt drehen (Kit3d-codeplex)
Hallo
Ich überlege krampfhaft wie ich es schaffen könnte eine Kamera um ein Objekt zu drehen. Im Moment bewege ich meine fertigen Mesh`s (einfache Rotation um y). Nun würde ich gern die Kamera drehen und finde kein gescheiten Anfang. In Delphi gibt es eine Funktion namens "MoveObjectAround". Ist es sinnvoll diese nachzubauen oder geht das auch einfacher?
Im Prinzip soll es am ende möglich sein per Mouseevent die Kamera einmal um das Objekt zu bewegen.
Kha - Mi 14.01.09 19:01
:welcome:
Da die Engine eine Camera-Klasse besitzt, ist mir nicht klar, an welcher Stelle du nicht weiterkommst. Wenn du z.B. eine PerspectiveCamera hast, musst du Position und LookDirection anpassen, dazu bieten sich
Kugelkoordinaten [
http://de.wikipedia.org/wiki/Kugelkoordinaten] an.
_Joe_ - Do 15.01.09 09:59
Gibt es dazu vielleicht ein Tutorial? So richtig schlau werde ich daraus nichts :)
Ich hab jetzt mit Hilfe der Kugelkoordinaten neue Punkte ausgerechnet die Kamera scheint sich auch zu bewegen, im welchen Verhältnis muss ich jetzt die LookDirection verändern?
Kha - Do 15.01.09 16:59
LookDirection ist ein Vektor in Richtung Objekt von der Kamera aus, sollte sich also doch relativ leicht ausrechnen lassen, wenn du die Vektoren von Kamera und Objekt hast ;) .
_Joe_ - Fr 16.01.09 10:19
Irgendwie hab ich dann doch ein Verständnis Problem.
Im Moment nehme ich einen Punkt rechne diesen in Kugelkoordinaten um, nehme dann die Formel für die Jacobie Rotationsmatrix und Multipliziere die Matrix mit dem alten Vektor. Dann bekomme ich ein neuen Vektor der doch eigentlich die Verschiebung auf der Kreisbahn sein sollte?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88:
| class Kugelkoordinaten { private double arccot(double x) { double ergebniss = 0; if (x < 0) ergebniss = Math.PI + Math.Atan(1 / Math.PI); if (x == 0) ergebniss = Math.PI / 2; if (x > 0) ergebniss = Math.Atan(1 / x); return ergebniss; }
public Vector3D ruecktransformation(double r, double beta, double gamma) { double x,y,z; x = r * Math.Sin(gamma) * Math.Cos(beta); y = r * Math.Sin(gamma) * Math.Sin(beta); z = r * Math.Cos(gamma); Vector3D vec = new Vector3D(x,y,z); return vec; }
public double[,] rotationsmatrix (double beta, double gamma) { double[,] matrix = new double[3,3]; matrix[0,0] = Math.Sin(gamma) * Math.Sin(beta); matrix[1,0] = Math.Cos(gamma) * Math.Sin(beta); matrix[2,0] = Math.Sin(beta)*-1;
matrix[0,1] = Math.Sin(gamma) * Math.Sin(beta); matrix[1,1] = Math.Cos(gamma) * Math.Sin(beta); matrix[2,1] = Math.Cos(beta);
matrix[0,2] = Math.Cos(gamma); matrix[1,2] = Math.Sin(gamma); matrix[2,2] = 0; return matrix; }
public Vector3D matrix_vector(double[,] m_matrix, Vector3D m_vec) { Vector3D vec = new Vector3D(); vec.X = m_matrix[0, 0] * m_vec.X + m_matrix[1,0] * m_vec.Y + m_matrix[2,0] * m_vec.Z; vec.Y = m_matrix[0, 1] * m_vec.X + m_matrix[1,1] * m_vec.Y + m_matrix[2,1] * m_vec.Z; vec.Z = m_matrix[0, 2] * m_vec.X + m_matrix[1,2] * m_vec.Y + m_matrix[2,2] * m_vec.Z; return vec; }
public Vector3D punktVektor(double x, double y, double z) { double r = 0, beta = 0, gamma = 0; r = Math.Sqrt((x * x) + (y * y) + (z * z)); if (y >= 0) beta = Math.Acos(x / (Math.Sqrt((x * x) + (y * y)))); if (y < 0) beta = 2 * Math.PI - Math.Acos(x / (Math.Sqrt((x * x) + (y * y)))); gamma = arccot(z / (Math.Sqrt((x * x) + (y * y)))); Vector3D vector = new Vector3D(r, beta, gamma); return vector; }
}
class Program {
static void Main(string[] args) { Kugelkoordinaten a = new Kugelkoordinaten(); Vector3D vec = new Vector3D(); double[,] matrix; vec = a.punktVektor(2, 1, 1); Console.WriteLine("Kugelkoordinaten: "); Console.WriteLine("radius: " + vec.X); Console.WriteLine("beta: " + vec.Y); Console.WriteLine("gamma: " + vec.Z); matrix = a.rotationsmatrix(vec.Y, vec.Z); vec = a.matrix_vector(matrix, new Vector3D(2,1,1)); Console.WriteLine("\nNeuer Vektor mit Jaccobi Matrix: "); Console.WriteLine("X: " + vec.X); Console.WriteLine("Y: " + vec.Y); Console.WriteLine("Z: " + vec.Z); Console.Read(); } } |
Moderiert von Christian S.: Quote- durch C#-Tags ersetzt
Kha - Fr 16.01.09 12:32
Wenn es ums Drehen per Maus/Timer geht, reicht es meistens auch aus, nur die zwei Drehwinkel zu speichern. Über diese rechnest du dann die Kameraposition C aus, Karth.->Kugelkoordinaten brauchst du damit gar nicht. Und wenn das Objekt im Ursprung liegt, ist die LookDirection -C.
_Joe_ - Fr 16.01.09 12:50
Also ich speicher mir jetzt die X Richtung und die Y Richtung der Maus.
Und wie Rechne ich die Kontraposition aus?
Ich kann doch nicht der erste Mensch der Welt sein der eine Kamera um ein Mesh drehen will :D
Kennst du vielleicht ein brauchbaren link wo mal nicht mit GL gearbeitet wird?
Kha - Fr 16.01.09 13:12
_Joe_ hat folgendes geschrieben : |
Und wie Rechne ich die Kontraposition aus? |
Die was :gruebel: ?
Erstmal musst du ein sinnvolles Verhältnis von Mausbewegung und Drehwinkeln finden, z.B. 200 Pixel = 2 Pi. Die zwei Winkel stopfst du dann in dein
ruecktransformation, Radius ist der Abstand Objekt-Kamera. Der Gegenvektor des Ergebnisses ist dann gleichzeitig deine LookDirection. Und wenn das Objekt nicht im Ursprung liegt, musst du für die endgültige Kamera-Position noch den Objekt-Vektor addieren.
PS: Ich wollte gerade nachschauen, wie ich das selbst gemacht habe, aber ich habe die Kamera statisch gelassen und einfach das Objekt gedreht - was vor Allem daran liegt, dass es bei DirectX gar nicht anders geht :mrgreen: .
C#-Quelltext
1:
| x.device.Transform.World = Matrix.RotationZ(-phi) * Matrix.RotationY(theta); |
_Joe_ - Fr 16.01.09 14:01
Kontraposition = Kameraposition
buuhhhh ein viel zu großes Framework
danke, sollte reichen
_Joe_ - Mo 19.01.09 10:45
so richtig schön ist das nicht, wenn ich die Kamera nur um die Y-Achse drehe ist es in Ordnung aber um die X-Achse siehst ganz schön komisch aus.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| public void camvie(double r,double x,double y) { double beta, gamma, z; beta = x * ((2 * Math.PI) / 400); gamma = y * ((2 * Math.PI) / 400); x = r * Math.Sin(gamma) * Math.Cos(-beta); y = r * Math.Sin(gamma) * Math.Sin(-beta); z = (r * Math.Cos(gamma)); cam.Position = new Point3D(x,y,z); cam.LookDirection = new Vector3D(-x,-y,-z); } |
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| private void grid_left_MouseMove(object sender, MouseEventArgs e) { if (mousebutton == true) { Point mouspoint = e.GetPosition(grid_left); geometry.camvie(8,mouspoint.Y,mousepoint.X); AddText(grid_right,"Mousepoint: \nX: " + mouspoint.X+ "Y: " + mouspoint.Y); } } |
Gibt es noch eine andere Möglichkeit?
Kha - Mo 19.01.09 12:33
Da es ja um Silverlight geht, könntest du die App irgendwo hochladen? Sonst kann ich mit "komisch" leider wenig anfangen ;) .
_Joe_ - Mo 19.01.09 16:37
Kann ich heute Abend mal machen.
*update*
_Joe_ - Di 20.01.09 17:36
*update*
Kha - Di 20.01.09 18:00
Das dürfte am UpVector der Kamera liegen. Default ist (0,1,0), du brauchst aber (0,0,1).
_Joe_ - Di 20.01.09 20:57
schau ich morgen mal Danke :beer:
So das wahre ist es immer noch nicht, ab einem bestimmten Punkt springt das Objekt um 90° :-/.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| public void kamera_maus(double r, double x, double y) { double beta, gamma, z; beta = x * ((2 * Math.PI) / 800); gamma = y * ((2 * Math.PI) / 800); x = -r * Math.Sin(gamma) * Math.Cos(beta); y = -r * Math.Sin(gamma) * Math.Sin(beta); z = -r * Math.Cos(gamma); cam.Position = new Point3D(x, y, z); cam.LookDirection = new Vector3D(-x, -y, -z); cam.UpDirection = new Vector3D(0, 0, 1); } |
wobei r-Radius, x Mausposition in X Richtung und Y Mausposition in Y Richtung
_Joe_ - Do 22.01.09 17:38
Es wird sogar noch schlimmer :D.
nicht alle Geometrien haben ihr Mitte im Nullpunkt. Ich könnte denn Mittelpunkt aller Geometrien berechnen, nur verknüpfe ich das mit der Kamera :gruebel:
Kha - Do 22.01.09 18:37
_Joe_ hat folgendes geschrieben : |
Ich könnte denn Mittelpunkt aller Geometrien berechnen, nur verknüpfe ich das mit der Kamera :gruebel: |
Darf ich da ein "wie" ergänzen ;) ? Da alle Berechnungen von einem Objekt im Ursprung ausgegangen sind, musst du den Mittelpunkt nur zur Kameraposition dazuaddieren (_nach_ Setzen der LookDirection).
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!