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