Einzelnen Beitrag anzeigen

Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#12

Re: Drehung eines Körpers um eine beliebige Achse

  Alt 5. Mai 2009, 19:36
Ich hab mir doch noch ein paar Gedanken gemacht und kurzerhand mal was programmiert

Man kann den Würfel um die verschiedenen Achsten drehen, mittels der Trackbars unten.

Man kann die Projektion auswählen

Man kann dem lustigen Farbenspiel zusehen, weil ich nicht die Muße hatte, die Flächen einzeln zu färben.

Hier ist der Code:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Test_1
{
    public partial class Form1 : Form
    {
        PointF offset;

        Vector3D[] Punkte;

        Matrix3x3 RotX;
        Matrix3x3 RotY;
        Matrix3x3 RotZ;

        Pen pen;
        Brush brush;

        Projektion p;

        public Form1()
        {
            InitializeComponent();

            offset = new PointF(300, 200);

            Punkte = new Vector3D[8];

            Punkte[0] = new Vector3D(-100, -100, 100);
            Punkte[1] = new Vector3D(100, -100, 100);
            Punkte[2] = new Vector3D(100, 100, 100);
            Punkte[3] = new Vector3D(-100, 100, 100);
            Punkte[4] = new Vector3D(-100, 100, -100);
            Punkte[5] = new Vector3D(100, 100, -100);
            Punkte[6] = new Vector3D(100, -100, -100);
            Punkte[7] = new Vector3D(-100, -100, -100);

            RotX = new Matrix3x3();
            RotY = new Matrix3x3();
            RotZ = new Matrix3x3();

            pen = new Pen(Color.Blue);
            pen.Width = 3;
            brush = new SolidBrush(Color.Red);

            p = Projektion.Zentral;
        }

        public void Draw()
        {
            pictureBox1.Invalidate();
        }

        public Vector3D Multiply(Matrix3x3 A, Vector3D b)
        {
            Vector3D Result;
            Result.X = A[0, 0] * b.X + A[0, 1] * b.Y + A[0, 2] * b.Z;
            Result.Y = A[1, 0] * b.X + A[1, 1] * b.Y + A[1, 2] * b.Z;
            Result.Z = A[2, 0] * b.X + A[2, 1] * b.Y + A[2, 2] * b.Z;
            return Result;
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Vector3D[] Points = (Vector3D[])Punkte.Clone();

            // Rotation
            for (int i = 0; i < Points.Length; i++)
            {
                Points[i] = Multiply(RotX, Points[i]);
            }

            // Rotation
            for (int i = 0; i < Points.Length; i++)
            {
                Points[i] = Multiply(RotY, Points[i]);
            }

            // Rotation
            for (int i = 0; i < Points.Length; i++)
            {
                Points[i] = Multiply(RotZ, Points[i]);
            }


            PointF[] dp = new PointF[Points.Length];

            for (int i = 0; i < Points.Length; i++)
            {
                dp[i] = Points[i].ToPoint(p);
                dp[i].X += offset.X;
                dp[i].Y += offset.Y;

            }

            e.Graphics.FillPolygon(brush, dp);
            e.Graphics.DrawPolygon(pen, dp);
            e.Graphics.DrawLine(pen, dp[0], dp[3]);
            e.Graphics.DrawLine(pen, dp[4], dp[7]);
            e.Graphics.DrawLine(pen, dp[1], dp[6]);
            e.Graphics.DrawLine(pen, dp[2], dp[5]);
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            double alpha = trackBar1.Value * Math.PI / 180;
            RotX[1, 1] = (float)Math.Cos(alpha);
            RotX[1, 2] = -1 * (float)Math.Sin(alpha);
            RotX[2, 1] = (float)Math.Sin(alpha);
            RotX[2, 2] = (float)Math.Cos(alpha);
            Draw();
        }

        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            double alpha = trackBar2.Value * Math.PI / 180;
            RotY[0, 0] = (float)Math.Cos(alpha);
            RotY[0, 2] = -1 * (float)Math.Sin(alpha);
            RotY[2, 0] = (float)Math.Sin(alpha);
            RotY[2, 2] = (float)Math.Cos(alpha);
            Draw();
        }

        private void trackBar3_Scroll(object sender, EventArgs e)
        {
            double alpha = trackBar3.Value * Math.PI / 180;
            RotZ[0, 0] = (float)Math.Cos(alpha);
            RotZ[0, 1] = -1 * (float)Math.Sin(alpha);
            RotZ[1, 0] = (float)Math.Sin(alpha);
            RotZ[1, 1] = (float)Math.Cos(alpha);
            Draw();
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            Vector3D.effect = (float)numericUpDown1.Value / 10000f;
            Draw();
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            p = radioButton1.Checked ? Projektion.Parallel : Projektion.Zentral;
            Draw();
        }
    }

    public enum Projektion {Parallel, Zentral};

    public struct Vector3D
    {
        public float X, Y, Z;

        public static float effect = 0.002f;

        public Vector3D(float x, float y, float z)
        {
            X = x;
            Y = y;
            Z = z;
        }

        public PointF ToPoint(Projektion art)
        {
            switch (art)
            {
                case Projektion.Parallel:
                    return new PointF(X, Y);
                case Projektion.Zentral:
                    return new PointF(X * (1 - effect * Z), Y * (1 - effect * Z));
                default:
                    throw new Exception();
            }
        }

        public void Add(Vector3D b)
        {
            X += b.X;
            Y += b.Y;
            Z += b.Z;
        }
    }

    public class Matrix3x3
    {
        private float[,] values;

        public Matrix3x3()
        {
            values = new float[3, 3];
            values[0, 0] = 1;
            values[1, 1] = 1;
            values[2, 2] = 1;
        }

        public float this[byte row, byte col]
        {
            get { return values[row, col]; }
            set { values[row, col] = value; }
        }

        public override String ToString()
        {
            String result = "";
            for (int i = 0; i < 3; i++)
            {
                result += "|  ";
                for (int j = 0; j < 3; i++)
                {
                    result += String.Format("%0.00" + Convert.ToChar(8), values[i, j]);
                }
                result += " |\r\n";
            }
            return result;
        }
    }
}
Programm im Anahng
Angehängte Dateien
Dateityp: exe test_1_445.exe (14,0 KB, 45x aufgerufen)
  Mit Zitat antworten Zitat