Einzelnen Beitrag anzeigen

Benutzerbild von jfheins
jfheins

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

Re: Optische Verkürzung

  Alt 18. Nov 2009, 09:43
Hab dir da mal was gecodet

Ist jetzt zwar Q&D und es hat auch ein bisschen gedauert bis das einigermaßen hingehauen hat - aber es dürfte deinen Anforderungen schon nahe kommen

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
    {
        RectangleF Outline;
        byte Rows = 8;
        byte Cols = 8;

        Pen pen;

        public Form1()
        {
            InitializeComponent();

            pen = new Pen(Color.Black, 2);

            Outline = new RectangleF(-200, 0, 400, 400);
        }

        private PointF DisplayTransform(PointF coord)
        {
            PointF Result = new PointF();
            Result.X = coord.X + pictureBox1.Width / 2;
            Result.Y = coord.Y + pictureBox1.Height * 0.8f;
            return Result;
        }

        private PointF Transform(PointF coord)
        {
            // Trapezverzerrung

            coord.X = coord.X * ( 1 - coord.Y * ((float)trackBar3.Value / 10000f));

            // Rotation um die x-Achse
            // gleichzeitug: Parallelprojektion
            // (Im Grunde geht man kurz in den 3D-Raum um dann die Z-Komponente wegzuwerfen,
            // da kann man sich die aber auch direkt sparen)
            coord.Y = coord.Y * (float)Math.Sin(trackBar1.Value * Math.PI / 180);

            return coord;
        }

        private void Transform(ref PointF[] coords)
        {
            for (int i = 0; i < coords.Length; i++)
            {
                coords[i] = DisplayTransform(Transform(coords[i]));
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            float colwidth = Outline.Width / (float)Cols;
            float rowheight = Outline.Height / (float)Rows;

            PointF[] Feld = new PointF[4];

            Brush farbe;

            for (int row = 0; row < Rows; row++)
            {
                for (int col = 0; col < Cols; col++)
                {
                    var left = Outline.Left + col * colwidth;
                    var top = Outline.Top + row * rowheight;

                    Feld[0] = new PointF(left, top);
                    Feld[1] = new PointF(left + colwidth, top);
                    Feld[2] = new PointF(left + colwidth, top + rowheight);
                    Feld[3] = new PointF(left, top + rowheight);

                    Transform(ref Feld);

                    if ((row + col + 1) % 2 == 0)
                        farbe = Brushes.Black;
                    else
                        farbe = Brushes.White;

                    e.Graphics.FillPolygon(farbe, Feld);
                }
            }


            Feld[0] = new PointF(Outline.Left, Outline.Top);
            Feld[1] = new PointF(Outline.Left + Outline.Width, Outline.Top);
            Feld[2] = new PointF(Outline.Left + Outline.Width, Outline.Top + Outline.Height);
            Feld[3] = new PointF(Outline.Left, Outline.Top + Outline.Height);

            Transform(ref Feld);

            e.Graphics.DrawPolygon(pen, Feld);
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            var a = 10 * Math.Cos((360 - trackBar1.Value) * Math.PI / 180);
            trackBar3.Value = (int)a;
            pictureBox1.Invalidate();
        }

        private void trackBar3_Scroll(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();

        }
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();
        } 
    }
}
Der ober Schieber steuert die "Drehung" und der untere steuert die Trapezverzerrung. Um eine ordentliche Perspektive hinzubekommen müssen diese beiden passend gekoppelt sein. Hab das jetzt einfach mal probiert (wenn man den oberen Schiber bewegt, wird der untere auch angepasst)

Programm im Anahng
Angehängte Dateien
Dateityp: exe test_1_149.exe (10,0 KB, 2x aufgerufen)
  Mit Zitat antworten Zitat