Rotation eines Würfels

  • C#

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von Pascalony.

    Rotation eines Würfels

    Hallo Forum,

    ich habe einen Würfel den ich einfach durch f(x, y, z) = (x + z, y + z) auf den Bildschirm projeziere. Jetzt wollte ich ihn rotieren lassen und verwende dafür die folgende Formel: en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations

    Das Problem ist, dass ich den Würfel gerne um sich selbst also seinen Mittelpunkt o.ä rotieren möchte. Ich weiß nichtmal worum her rotiert (außer in welche Richtung) aber er verlässt den Bildschirm zwischendurch, d.h er läuft einen riesigen Weg. Ich möchte hierbei meine eigene 3x3 Matrix verwenden und nicht die RotateAt-Methode von C#.

    C#-Quellcode

    1. public class Cube
    2. {
    3. public Vector3[] Vertices { get; set; }
    4. public Cube(float offset, float width, float height, float depth)
    5. {
    6. Vertices = new Vector3[8];
    7. Vertices[0] = new Vector3(offset, offset, offset);
    8. Vertices[1] = new Vector3(width + offset, offset, offset);
    9. Vertices[2] = new Vector3(width + offset, depth + offset, offset);
    10. Vertices[3] = new Vector3(offset, depth + offset, offset);
    11. Vertices[4] = new Vector3(offset, offset, height + offset);
    12. Vertices[5] = new Vector3(width + offset, offset, height + offset);
    13. Vertices[6] = new Vector3(width + offset, depth + offset, height + offset);
    14. Vertices[7] = new Vector3(offset, depth + offset, height + offset);
    15. }
    16. public void Rotate(Matrix3x3 rotation)
    17. {
    18. for(var i = 0; i < Vertices.Count(); i++)
    19. {
    20. Vertices[i] *= rotation;
    21. }
    22. }
    23. public void Draw(Graphics device)
    24. {
    25. Vector2[] temp = new Vector2[8];
    26. for(var i = 0; i < Vertices.Count(); i++)
    27. {
    28. temp[i] = new Vector2(Vertices[i].X + 0.5 * Vertices[i].Z, Vertices[i].Y + 0.5 * Vertices[i].Z);
    29. }
    30. Pen pen = new Pen(Brushes.Black, 2f);
    31. device.DrawLine(pen, (float)temp[0].X.ToDouble(), (float)temp[0].Y.ToDouble(), (float)temp[1].X.ToDouble(), (float)temp[1].Y.ToDouble());
    32. device.DrawLine(pen, (float)temp[0].X.ToDouble(), (float)temp[0].Y.ToDouble(), (float)temp[3].X.ToDouble(), (float)temp[3].Y.ToDouble());
    33. device.DrawLine(pen, (float)temp[0].X.ToDouble(), (float)temp[0].Y.ToDouble(), (float)temp[4].X.ToDouble(), (float)temp[4].Y.ToDouble());
    34. device.DrawLine(pen, (float)temp[1].X.ToDouble(), (float)temp[1].Y.ToDouble(), (float)temp[2].X.ToDouble(), (float)temp[2].Y.ToDouble());
    35. device.DrawLine(pen, (float)temp[1].X.ToDouble(), (float)temp[1].Y.ToDouble(), (float)temp[5].X.ToDouble(), (float)temp[5].Y.ToDouble());
    36. device.DrawLine(pen, (float)temp[2].X.ToDouble(), (float)temp[2].Y.ToDouble(), (float)temp[3].X.ToDouble(), (float)temp[3].Y.ToDouble());
    37. device.DrawLine(pen, (float)temp[2].X.ToDouble(), (float)temp[2].Y.ToDouble(), (float)temp[6].X.ToDouble(), (float)temp[6].Y.ToDouble());
    38. device.DrawLine(pen, (float)temp[3].X.ToDouble(), (float)temp[3].Y.ToDouble(), (float)temp[7].X.ToDouble(), (float)temp[7].Y.ToDouble());
    39. device.DrawLine(pen, (float)temp[4].X.ToDouble(), (float)temp[4].Y.ToDouble(), (float)temp[5].X.ToDouble(), (float)temp[5].Y.ToDouble());
    40. device.DrawLine(pen, (float)temp[4].X.ToDouble(), (float)temp[4].Y.ToDouble(), (float)temp[7].X.ToDouble(), (float)temp[7].Y.ToDouble());
    41. device.DrawLine(pen, (float)temp[5].X.ToDouble(), (float)temp[5].Y.ToDouble(), (float)temp[6].X.ToDouble(), (float)temp[6].Y.ToDouble());
    42. device.DrawLine(pen, (float)temp[6].X.ToDouble(), (float)temp[6].Y.ToDouble(), (float)temp[7].X.ToDouble(), (float)temp[7].Y.ToDouble());
    43. }
    44. }



    C#-Quellcode

    1. public partial class Form1 : Form
    2. {
    3. public Form1()
    4. {
    5. InitializeComponent();
    6. }
    7. private Cube cube;
    8. private Matrix3x3 rotation;
    9. private void Form1_Load(object sender, EventArgs e)
    10. {
    11. DoubleBuffered = true;
    12. cube = new Cube(250f, 50f, 50f, 50f);
    13. rotation = new Matrix3x3();
    14. rotation.M11 = 1f;
    15. rotation.M12 = 0f;
    16. rotation.M13 = 0f;
    17. rotation.M21 = 0f;
    18. rotation.M22 = (float)Math.Cos(0.005);
    19. rotation.M23 = (float)-Math.Sin(0.005);
    20. rotation.M31 = 0f;
    21. rotation.M32 = (float)Math.Sin(0.005);
    22. rotation.M33 = (float)Math.Cos(0.005);
    23. }
    24. private void Form1_Paint(object sender, PaintEventArgs e)
    25. {
    26. cube.Draw(e.Graphics);
    27. }
    28. private void timer1_Tick(object sender, EventArgs e)
    29. {
    30. cube.Rotate(rotation);
    31. Invalidate(false);
    32. Update();
    33. }
    34. }


    Ich habe zwei Anhänge hinzugefügt, damit man sieht was ich mich "zu weiter" Rotation meine.

    Danke im Voraus
    Bilder
    • Rotate 1.png

      6,65 kB, 1.165×787, 82 mal angesehen
    • Rotate 2.png

      6,38 kB, 1.144×716, 86 mal angesehen

    entweder du veränderst die Vertices so, dass der Nullpunkt der Mittelpunkt des Würfels ist und verschiebst in nur durch eine anschließende Translationsmatrix(oder auch direkt), damit kannst du dann eine normale Rotationsmatrix verwenden, oder du machst eine Translationsmatrix, die den Würfel so bewegt, dass der Nullpunkt der Mittelpunkt des Würfels ist, rotierst anschließend mit deiner Rotationsmatrix und bewegst den Würfel wieder zurück. Das kann man natürlich auch mit einer einzigen Matrix darstellen.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    @jvbsl Jou.
    @Pascalony Überlege: Welche Koordinaten hat der Mittelpunkt Deines Würfels momentan? Hinsehen, nicht rechnen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Pascalony schrieb:

    aber was meinst du mit "hinsehen, nicht rechnen"?
    Du setzt die Ecken Deines Würfels mit Width und Offset. Das ist einfach eine Übung zur Schulung des räumlichen Vorstellungsvermögens.
    Bei ähnlichen Problemen (auch 2D) weißt Du dann sofort, wo das Problem liegt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!