Сортировка при удалении невидимых частей - 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))
{