Сортировка при удалении невидимых частей - C#
Формулировка задачи:
Есть прога, которая генерирует несколько треугольников в пространстве и удаляет невидимые части методом построчного сканирования с использованием z-буфера. После генерации точек каждого треугольника, выполняется некая сортировка, c помощью которой выполняется проверка на то, попал ли проверяемый пиксель внутрь треугольника.
Не понимаю, что такое k1, b1, znak2 znak3 (zBuffer 64-71) и каким образом с помощью них выполняется та самая проверка на попадание? Понятное дело, что вычисление k1,b1 и т.д. производятся по какой-то формуле. Формулы этой я найти не смог. Может кто ее узнает.
Form1.cs
zBuffer.cs
// построчное сканирование с использованием z-буфера using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace lab2 { public partial class main : Form { public Graphics Grafica; public Figure[] Figure; public Color[] RGB; public Random Random; public int Count; public double ZBuffer; public Color FrameBuffer; public main() { InitializeComponent(); Grafica = this.CreateGraphics(); Random = new Random(unchecked((int)DateTime.Now.Ticks)); Count = Random.Next(3, 10); Figure = new Figure[Count]; RGB = new Color[10]; RGB[0] = Color.Aqua; RGB[1] = Color.Red; RGB[2] = Color.Orange; RGB[3] = Color.Yellow; RGB[4] = Color.Green; RGB[5] = Color.BlueViolet; RGB[6] = Color.CornflowerBlue; RGB[7] = Color.Chocolate; RGB[8] = Color.LemonChiffon; RGB[9] = Color.PeachPuff; } private void button1_Click(object sender, EventArgs e) { //Генерация полигонов Grafica.Clear(this.BackColor); for (int i = 0; i < Count; i++) { Figure[i] = new Figure(); Figure[i].count_vertex = 3; Figure[i].Point = new Point3D[Figure[i].count_vertex]; Figure[i].color = RGB[i]; //Генерация точек полигона for (int j = 0; j < 3; j++) { Figure[i].Point[j] = new Point3D(); Figure[i].Point[j].x = Random.Next(-150, 150); Figure[i].Point[j].y = Random.Next(-150, 150); Figure[i].Point[j].z = Random.Next(-500, 500); } //Определение коэффициентов уравнения плоскости по методу Ньюэла Figure[i].A = Figure[i].Point[0].y * (Figure[i].Point[1].z - Figure[i].Point[2].z) + Figure[i].Point[1].y * (Figure[i].Point[2].z - Figure[i].Point[0].z) + Figure[i].Point[2].y * (Figure[i].Point[0].z - Figure[i].Point[1].z); Figure[i].B = Figure[i].Point[0].z * (Figure[i].Point[1].x - Figure[i].Point[2].x) + Figure[i].Point[1].z * (Figure[i].Point[2].x - Figure[i].Point[0].x) + Figure[i].Point[2].z * (Figure[i].Point[0].x - Figure[i].Point[1].x); Figure[i].C = Figure[i].Point[0].x * (Figure[i].Point[1].y - Figure[i].Point[2].y) + Figure[i].Point[1].x * (Figure[i].Point[2].y - Figure[i].Point[0].y) + Figure[i].Point[2].x * (Figure[i].Point[0].y - Figure[i].Point[1].y); Figure[i].D = -(Figure[i].Point[0].x * (Figure[i].Point[1].y * Figure[i].Point[2].z - Figure[i].Point[2].y * Figure[i].Point[1].z) + Figure[i].Point[1].x * (Figure[i].Point[2].y * Figure[i].Point[0].z - Figure[i].Point[0].y * Figure[i].Point[2].z) + Figure[i].Point[2].x * (Figure[i].Point[0].y * Figure[i].Point[1].z - Figure[i].Point[1].y * Figure[i].Point[0].z)); Figure[i].Sort(); } //Отрисовка полигонов float cx = this.Width / 2, cy = this.Height / 2; for (int i = 0; i < Count; i++) { Pen pen = new Pen(Figure[i].color, 2); Grafica.DrawLine(pen, (float)Figure[i].Point[0].x + cx, (float)Figure[i].Point[0].y + cy, (float)Figure[i].Point[1].x + cx, (float)Figure[i].Point[1].y + cy); Grafica.DrawLine(pen, (float)Figure[i].Point[0].x + cx, (float)Figure[i].Point[0].y + cy, (float)Figure[i].Point[2].x + cx, (float)Figure[i].Point[2].y + cy); Grafica.DrawLine(pen, (float)Figure[i].Point[2].x + cx, (float)Figure[i].Point[2].y + cy, (float)Figure[i].Point[1].x + cx, (float)Figure[i].Point[1].y + cy); } } private void button2_Click(object sender, EventArgs e) { int m1; float cx = this.Width / 2, cy = this.Height / 2; for (int y = -150; y < 150; y++) { for (int x = -150; x < 150; x++) { FrameBuffer = Color.Black; ZBuffer = -100500000000; for (int i = 0; i < Count; i++) { if (x >= (y - Figure[i].b1) / Figure[i].k1) { if ((Figure[i].znak2 == true && y < Figure[i].k2 * x + Figure[i].b2) || (Figure[i].znak2 == false && y > Figure[i].k2 * x + Figure[i].b2)) { if ((Figure[i].znak3 == true && y < Figure[i].k3 * x + Figure[i].b3) || (Figure[i].znak3 == false && y > Figure[i].k3 * x + Figure[i].b3)) { //вычисляем глубину каждого пиксела. по уравнению плоскости int z = (int)((-Figure[i].D - Figure[i].A * x - Figure[i].B * y) / Figure[i].C); if (ZBuffer < z) { ZBuffer = z; FrameBuffer = Figure[i].color; } } } } } Pen pen = new Pen(FrameBuffer, 2); Grafica.DrawEllipse(pen, x + cx, y + cy, 1, 1); Grafica.DrawRectangle(pen, x + cx, 160 + cy, 1, 10); } } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; namespace lab2 { //Точка в пространсве public class Point3D { public double x, y, z; } public class Figure { public int count_vertex; //число вершин public Color color; //цвет public Point3D[] Point = new Point3D[3];//массив вершин public double A, B, C, D; public double k1, b1, k2, b2, k3, b3; public bool znak2,znak3; public void Sort() { Point3D MaxPoint = this.Point[0], MinPoint = Point[0]; int MaxIndex = 0, MinIndex = 0; for (int i = 1; i < 3; i++) { if (Point[i].y > MaxPoint.y) { MaxPoint = Point[i]; MaxIndex = i; } if (Point[i].y < MinPoint.y) { MinPoint = Point[i]; MinIndex = i; } } int MidIndex = 3 - MaxIndex - MinIndex; Point3D MidPoint = Point[MidIndex]; double k = (MaxPoint.y - MinPoint.y) / (MaxPoint.x - MinPoint.x); //угловой коэффициент double b = MaxPoint.y - k * MaxPoint.x; //свободный член double tx_sr = (MidPoint.y - b) / k; if (tx_sr > MidPoint.x) { Point[0] = MaxPoint; Point[1] = MidPoint; Point[2] = MinPoint; } else { Point[0] = MaxPoint; Point[1] = MinPoint; Point[2] = MidPoint; } k1 = (Point[0].y - Point[1].y) / (Point[0].x - Point[1].x); b1 = Point[1].y - k1*Point[1].x; k2 = (Point[0].y - Point[2].y) / (Point[0].x - Point[2].x); b2 = Point[0].y - k2*Point[0].x; k3 = (Point[1].y - Point[2].y) / (Point[1].x - Point[2].x); b3 = Point[1].y - k3 * Point[1].x; if (Point[1].y < k2 * Point[1].x + b2) znak2 = true; else znak2 = false; if (Point[0].y < k3 * Point[0].x + b3) znak3 = true; else znak3 = false; } } }
Решение задачи: «Сортировка при удалении невидимых частей»
textual
Листинг программы
if (x >= (y - Figure[i].b1) / Figure[i].k1) { if ((Figure[i].znak2 == true && y < Figure[i].k2 * x + Figure[i].b2) || (Figure[i].znak2 == false && y > Figure[i].k2 * x + Figure[i].b2)) { if ((Figure[i].znak3 == true && y < Figure[i].k3 * x + Figure[i].b3) || (Figure[i].znak3 == false && y > Figure[i].k3 * x + Figure[i].b3)) {
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д