Обратите внимание, что это учебное упражнение для меня, поэтому я не использую сторонние библиотеки или матричные преобразования, представленные в .net. Пример, включенный ниже, отображает куб в форме и позволяет вращать, используя мышь. Это работает нормально, и теперь я пытаюсь реализовать масштаб на основе прокрутки колеса мыши. Если вы присмотритесь при прокрутке колеса мыши, это немного меняется. < /P>
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);
Я знаю, что мне еще предстоит понять прогнозы, матрицы и т. Д. На данный момент я просто хочу поэкспериментировать с основными формулами и построить оттуда. возможно): < /p>
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 ;
// 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 = 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);
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... 2d-surface
Проблема с масштабированием при проецировании 3D на 2D -поверхность ⇐ C#
Место общения программистов C#
-
Anonymous
1755429080
Anonymous
Обратите внимание, что это учебное упражнение для меня, поэтому я не использую сторонние библиотеки или матричные преобразования, представленные в .net. Пример, включенный ниже, отображает куб в форме и позволяет вращать, используя мышь. Это работает нормально, и теперь я пытаюсь реализовать масштаб на основе прокрутки колеса мыши. Если вы присмотритесь при прокрутке колеса мыши, это немного меняется. < /P>
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);
Я знаю, что мне еще предстоит понять прогнозы, матрицы и т. Д. На данный момент я просто хочу поэкспериментировать с основными формулами и построить оттуда. возможно): < /p>
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);
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79736741/issue-with-zooming-when-projecting-3d-on-to-a-2d-surface[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия