Probleme mit dem Zooming bei der Projektion von 3D auf eine 2D -Oberfläche projizierenC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Probleme mit dem Zooming bei der Projektion von 3D auf eine 2D -Oberfläche projizieren

Post by Anonymous »

Bitte beachten Sie, dass dies eine Lernübung für mich ist, daher verwende ich keine Bibliotheken von Drittanbietern oder Matrix-Transformationen, die in .NET bereitgestellt werden. Das unten enthaltene Beispiel zeigt einen Würfel auf einem Formular an und ermöglicht eine Rotation mit der Maus. Dies funktioniert einwandfrei, und ich versuche nun, das Zooming basierend auf dem Bildlauf des Mausrads zu implementieren. Wenn Sie beim Scrollen des Mausrads genau hinschauen, ändert sich es ein wenig. < /P>

Code: Select all

float CubeSize = 200; // Fixed.
float CameraDistance = 400; // Changes with mouse wheel.

// In the FormCube_MouseWheel event:
this.CameraDistance -= e.Delta * 0.1f; // Zoom sensitivity.
this.CameraDistance = Math.Max(100, Math.Min(1000, this.CameraDistance)); // Clamp

// In the OnPaint event:
var scale = this.CameraDistance / (this.CameraDistance + z2);
Ich weiß, dass ich im Moment noch keine Projektionen, Matrizen usw. verstanden habe. Ich möchte von dort nur nur mit grundlegenden Formeln experimentieren und bauen. möglich): < /p>

Code: Select all

using System;
using System.Drawing;
using System.Windows.Forms;

namespace GeometricVisualizer
{
internal static class Program
{
[STAThread]
private static void Main() => Application.Run(new FormCube());
}

public struct Point3D
{
public float X, Y, Z;
public Point3D(float x, float y, float z) { this.X = x; this.Y = y; this.Z = z; }
}

public partial class FormCube: Form
{
private Point MousePositionLast;
private bool MouseStateIsDragging;
private float
CameraAngleX = 0,
CameraAngleY = 0,
CubeSize = 200,
CameraDistance = 400;

private int EdgesDimensionLength0 = 12;
private int [,] Edges = new int [,]
{
{0, 1}, {1, 2}, {2, 3}, {3, 0},
{4, 5}, {5, 6}, {6, 7}, {7, 4},
{0, 4}, {1, 5}, {2, 6}, {3, 7},
};

private Point3D [] Cube = new Point3D []
{
new(x: -1, y: -1, z: -1),
new(x:  1, y: -1, z: -1),
new(x:  1, y:  1, z: -1),
new(x: -1, y:  1, z: -1),
new(x: -1, y: -1, z:  1),
new(x:  1, y: -1, z:  1),
new(x:  1, y:  1, z:  1),
new(x: -1, y:  1, z:  1),
};

private PointF [] CubeProjected = new PointF [8];

public FormCube ()
{
this.EdgesDimensionLength0 = this.Edges.GetLength(0);

this.KeyPreview = true;
this.DoubleBuffered = true;
this.Text = "3D Cube with Mouse Rotation";
this.WindowState = FormWindowState.Maximized;

this.KeyDown += this.FormCube_KeyDown;
this.MouseUp += this.FormCube_MouseUp;
this.MouseDown += this.FormCube_MouseDown;
this.MouseMove += this.FormCube_MouseMove;
this.MouseWheel += this.FormCube_MouseWheel;
this.Resize += this.FormCube_Resize;
this.ResizeEnd += this.FormCube_Resize;
this.ResizeBegin += this.FormCube_Resize;
}

private void FormCube_Resize (object? sender, EventArgs e)
=> this.Invalidate();

private void FormCube_KeyDown (object? sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up: { this.CameraAngleX -= 0.1f; break; }
case Keys.Down: { this.CameraAngleX += 0.1f; break; }
case Keys.Left: { this.CameraAngleY -= 0.1f; break; }
case Keys.Right: { this.CameraAngleY += 0.1f; break; }
case Keys.Add:
case Keys.Oemplus: { this.CameraDistance = Math.Max(100, this.CameraDistance - 20); break; }
case Keys.Subtract:
case Keys.OemMinus: { this.CameraDistance = Math.Min(1000, this.CameraDistance + 20); break; }
case Keys.R: { this.CameraAngleX = 0; this.CameraAngleY = 0; this.CameraDistance = 400; break; }
}

this.Invalidate();
}

private void FormCube_MouseDown (object? sender, MouseEventArgs e)
{
this.MouseStateIsDragging = true;
this.MousePositionLast = e.Location;
}

private void FormCube_MouseMove (object? sender, MouseEventArgs e)
{
if (this.MouseStateIsDragging)
{
var dx = e.X - this.MousePositionLast.X;
var dy = e.Y - this.MousePositionLast.Y;

this.CameraAngleY += dx * 0.01f;
this.CameraAngleX += dy * 0.01f;
this.MousePositionLast = e.Location;

this.Invalidate();
}
}

private void FormCube_MouseUp (object? sender, MouseEventArgs e)
=> this.MouseStateIsDragging = false;

private void FormCube_MouseWheel (object? sender, MouseEventArgs e)
{
this.CameraDistance -= e.Delta * 0.1f; // Zoom mouse sensitivity.
this.CameraDistance = Math.Max(100, Math.Min(1000, this.CameraDistance)); // Clamp zoom.

this.Invalidate();
}

protected override void OnPaint (PaintEventArgs e)
{
e.Graphics.Clear(Color.Black);

for (var i = 0; i < this.Cube.Length;  i++)
{
var p = this.Cube [i];

// Rotate around X axis.
var y1 = (p.Y * (float) Math.Cos(this.CameraAngleX)) - (p.Z * (float) Math.Sin(this.CameraAngleX));
var z1 = (p.Y * (float) Math.Sin(this.CameraAngleX)) + (p.Z * (float) Math.Cos(this.CameraAngleX));

// Rotate around Y axis.
var x2 = (p.X * (float) Math.Cos(this.CameraAngleY)) - (z1 * (float) Math.Sin(this.CameraAngleY));
var z2 = (p.X * (float) Math.Sin(this.CameraAngleY)) + (z1 * (float) Math.Cos(this.CameraAngleY));

var scale = this.CameraDistance / (this.CameraDistance + z2);
this.CubeProjected [i] = new PointF
(
(x2 * scale * this.CubeSize) + (this.ClientSize.Width / 2),
(y1 * scale * this.CubeSize) + (this.ClientSize.Height / 2)
);
}

for (var i = 0; i < this.EdgesDimensionLength0; i++)
{
e.Graphics.DrawLine(Pens.White, this.CubeProjected [this.Edges [i, 0]], this.CubeProjected [this.Edges [i, 1]]);
}

this.Text = $@"AngleX = {this.CameraAngleX}, AngleY = {this.CameraAngleY}, Zoom = {this.CameraDistance}.";

base.OnPaint(e);
}
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post