Моделирование геометрических объектов

Получение перспективных изображений на основе аналитической геометрии. Построение модели трехмерного объекта. Алгоритм изменения положения 3D объекта в пространстве. Нахождение нормали по 3 точкам. Определение невидимости граней и закраска методом Гуро.

Рубрика Математика
Вид курсовая работа
Язык русский
Дата добавления 19.10.2014
Размер файла 416,7 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

ВВЕДЕНИЕ

Геометрическое моделирование изучает методы построения математической модели, описывающей геометрические свойства предметов окружающего мира.

Инструментом для геометрического моделирования служат математические методы решения тех или иных задач. Используемые методы позволяют описать геометрические свойства предметов, создавать их математические модели и исследовать их путем проведения различных расчетов и численных экспериментов, а также, при необходимости, редактировать моделируемые объекты и строить их графические отображения.

Для описания геометрических свойств окружающих предметов строят твердые тела. Тело описывается точками, линиями и поверхностями. Все они обладают определенными общими свойствами, поэтому ими можно оперировать как объектами. Точки, линии, поверхности и тела называются геометрическими объектами.

Геометрические объекты будут служить основными элементами математической модели геометрии реальных или воображаемых объектов. Будем строить их в трехмерном евклидовом пространстве, считая их неименными во времени.

1. СОЗДАНИЕ МАТЕМАТИЧЕСКОЙ МОДЕЛИ ОБЪЕКТА

1.1 Преобразования координат

Рассмотрим способ получения перспективных изображений на основе аналитической геометрии. Точки в двухмерном и трехмерном пространстве представляются их координатами (X, Y) и (х, у, z) соответственно. При необходимости получения перспективной проекции задается большое количество точек P(x, у, z), принадлежащих объекту, для которых предстоит вычислить координаты точек изображения Р'(Х, Y) на картинке. Для этого нужно только преобразовать координаты точки Р из так называемых мировых координат (х, у, z) в экранные координаты (X, Y) ее центральной проекции Р'. Будем предполагать, что экран расположен между объектом и глазом Е. Для каждой точки Р объекта прямая линия РЕ пересекает экран в точке Р'.

Это отображение удобно выполнять в два этапа. Первый этап назовем видовым преобразованием - точка Р остается на своем месте, но система мировых координат переходит в систему видовых координат. Второй этап называется перспективным преобразованием. Это точное преобразование точки Р в точку Р' объединенное с переходом из системы трехмерных видовых координат в систему двухмерных экранных координат:

Для выполнения видовых преобразований должны быть заданы точка наблюдения и объект. Будет удобно, если начало системы мировых координатрасполагается вблизи центра объекта, поскольку объект наблюдается в направлении отЕ к О(рис.1). Пусть точка наблюденияЕ будет задана в сферических координатах f--,--q,----r по отношению к мировым координатам. То есть мировые координаты (точки Е) могут быть вычислены по формулам:

xe= r sin f----cos q--

ye=--r sin f-- sin q--------

ze= r cos f--.

Обозначения сферических координат схематически изображены на рис.1.

Рис. 1. Сферические координаты точки наблюдения Е

Видовое преобразование может быть записано в форме

[хe ye ze 1]=[хw уw zw 1]V,

где V - матрица видового преобразования размерами 4х4.

Матрица V, полученная в процессе видового преобразования, выглядит следующим образом:

.

Для получения ортогональной проекции можно использовать видовые координаты хe и уe, просто игнорируя координату ze. Каждая точка Р объекта проецируется в точку Р' проведением прямой линии из точки Р перпендикулярно плоскости, определяемой осями х и у. Эту проекцию можно также считать перспективной картинкой, которая была бы получена при удалении точки наблюдения в бесконечность. Параллельные линии остаются параллельными и на картинке, полученной при ортогональном проецировании.

1.2 Создание трехмерной модели

Для построения модели трехмерного объекта (например, куба) необходимо задать координаты его вершин в мировой системе координат, а затем получить из них видовые (и экранные для ортогональной проекции) координаты. Это можно сделать, описав координаты в массивах типа T3DPoint (запись, содержащая три координаты точки) и TPoint (запись, содержащая две координаты точки).

var
//мировые (world) координаты вершин
w: array [1..8] of T3DPoint;
//видовые (view) координаты вершин
v: array [1..8] of TPoint;
Для примера зададим координаты вершин куба с центром в начале координат:
w[1].x := -50; w[5].x := -50;
w[1].y := -50; w[5].y := -50;
w[1].z := -50; w[5].z := 50;
w[2].x := 50; w[6].x := 50;
w[2].y := -50; w[6].y := -50;
w[2].z := -50; w[6].z := 50;
w[3].x := 50; w[7].x := 50;
w[3].y := 50; w[7].y := 50;
w[3].z := -50; w[7].z := 50;
w[4].x := -50; w[8].x := -50;
w[4].y := 50; w[8].y := 50;
w[4].z := -50; w[8].z := 50;
Далее необходимо перевести координаты в видовую систему координат, воспользовавшись матрицей V. Подобная процедура может выглядеть следующим образом:
procedure ViewTransformation;
begin
for i := 1 to 8 Do
begin
v[i].x := Round(w[i].x*(-sin(teta)) +
w[i].y*( cos(teta))) +
Form1.ClientWidth div 2;
v[i].y := Round(w[i].x*(-cos(phi) * cos(teta)) -
w[i].y*( cos(phi) * sin(teta)) +
w[i].z*( sin(phi))) +
Form1.ClientHeight div 2;
end;
end;
Процедура отображения граней куба состоит в соединении между собой соответствующих вершин ребрами. Строить куб необходимо по видовым координатам, которые определены в процедуре ViewTransformation. Например:
procedure DrawCube;
begin
Line(v[1],v[2]);
Line(v[2],v[3]);
Line(v[4],v[1]);
Line(v[3],v[4]);
Line(v[5],v[6]);
Line(v[6],v[7]);
Line(v[7],v[8]);
Line(v[8],v[5]);
Line(v[1],v[5]);
Line(v[2],v[6]);
Line(v[3],v[7]);
Line(v[4],v[8]);
end;
На этом этапе можно вызвать процедуры ViewTransformation и DrawCube, например, из метода OnCreate, чтобы нарисовать куб. При этом необходимо проинициализировать начальные значения углов phi и teta.

2 АЛГОРИТМ ИЗМЕНЕНИЯ ПОЛОЖЕНИЯ 3D ОБЪЕКТА В ПРОСТРАНСТВЕ

2.1 Динамическое изменение точки наблюдения

Изменение расположения точки наблюдения приводит к изменению отображения объекта на экране (анимации). Для того чтобы добиться корректной анимации созданного трехмерного объекта, необходимо выполнить следующие шаги:

- Удалить объект из предыдущей позиции;

- Рассчитать новые координаты объекта;

- Нарисовать объект с новыми координатами.

2.2 Обработка нажатия клавиши

Получить скан-код клавиши, нажатой пользователем, а позволяет процедура FormKeyDown. В переменной Key передаётся код нажатой клавиши, который необходимо сравнить с кодами клавиш управления курсором. Для большей наглядности определены специальные константы: UP, DOWN, LEFT, RIGHT. В зависимости от нажатой клавиши изменяем углы phi и teta.

Перед изменением угла предстоит удалить старый рисунок. Это можно сделать с помощью закрашивания формы целиком цветомфона.

Листинг 3.Key.

private void Form1_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyCode == Keys.Left) teta -= Math.PI / 32;

if (e.KeyCode == Keys.Right) teta += Math.PI / 32;

if (e.KeyCode == Keys.Up) phi += Math.PI / 32;

if (e.KeyCode == Keys.Down) phi -= Math.PI / 32;

Repaint();

}

Обработка сообщений мыши

Если мы хотим изменять положение объекта с помощью мыши, мы обрабатываем сообщения MouseDown (нажатие на левую или правую кнопку мыши) или сообщение MouseMove (движение мыши, в этом случае можно проверять, в какую сторону происходит движение и в ту же сторону вращать фигуру).

Листинг 4.Mouse.

private void Form1_MouseDown(object sender, MouseEventArgs e)

{

xc = e.X;

yc = e.Y;

}

private void Form1_MouseMove(object sender, MouseEventArgs e)

{

if (e.Button == System.Windows.Forms.MouseButtons.Left)

{

int dx = e.X - xc;

intdy = e.Y - yc;

teta += dx * Math.PI / 128;

phi -= dy * Math.PI / 128;

xc = e.X;

yc = e.Y;

Repaint();

}

,,,

3 АЛГОРИТМ ЗАКРАШИВАНИЯ ПОЛИГОНА. АЛГОРИТМ, ОПРЕДЕЛЯЮЩИЙ ВИДИМЫЕ И НЕВИДИМЫЕ ЛИНИИ.

3.1 Нахождение нормали по трем точкам

Пусть заданы три точки (т.к. через любые три точки можно провести плоскость), например A, B, C. Уравнение плоскости задается в виде:

nx x + ny y + nz z + d=0,

где (nx, ny, nz) - координаты нормали к плоскости.

Получим систему уравнений:

nxx + nyy + nzz + d = 0

nxA.x + nyA.y + nzA.z + d = 0

nxB.x + nyB.y + nzB.z + d = 0

nxC.x + nyC.y + nzC.z + d = 0

В виде матрицы такая система запишется как:

|| xyz 1 ||

|| A.xA.yA.z 1 ||

|| B.xB.yB.z 1 || = 0

|| C.xC.yC.z 1 ||

Определитель будет равен (относительно первой строки):

|A.yA.z 1| |A.xA.z 1| |A.xA.y 1| |A.xA.y 1|

x |B.yB.z 1| - y |B.xB.z 1| + z |B.xB.y 1| - |B.xB.y 1|

|C.yC.z 1| |C.xC.z 1| |C.xC.y 1| |C.xC.y 1|

А так как через три точки всегда можно провести плоскость (притом только одну) и число уравнений данной системы равно числу неизвестных, следовательно, система имеет нетривиальное решение (кроме очевидногоnx=ny=nz=d=0). Следовательно, определитель данной матрицы равен нулю.

Получаем:

|A.yA.z 1|

nx = |B.yB.z 1|,

|C.yC.z 1|

|A.xA.z 1|

ny = |B.xB.z 1|,

|C.xC.z 1|

|A.xA.y 1|

nx = |B.xB.y 1|.

|C.xC.y 1|

Рассмотрим нахождение значения nx (остальные координаты получаются аналогично):

nx = A.y |B.z 1| - A.z |B.y 1| + |B.yB.z| =

|C.z 1| |C.y 1| |C.yC.z|

= A.y(B.z - C.z) - A.z(B.y - C.y) + (B.yC.z - B.zC.y) =

= A.y(B.z - C.z) + B.y(C.z - A.z) + C.y(A.z - B.z)

Итак, координаты вектора нормали:

nx = A.y(B.z - C.z) + B.y(C.z - A.z) + C.y(A.z - B.z)

ny = A.z(B.x - C.x) + B.z(C.x - A.x) + C.z(A.x - B.x) (10)

nz = A.x(B.y - C.y) + B.x(C.y - A.y) + C.x(A.y - B.y)

Для каждой грани при инициализации объекта нужно посчитать вектор нормали, привести к единичной длине и сохранить его координаты в структуре соответствующей грани. Кроме того, при каждом повороте сцены векторы нормали нужно тоже пересчитывать (но перспективную проекцию находить не следует).

3.2 Определение невидимости граней

трехмерный пространство моделирование геометрический

По углу между направлением взгляда и нормалью можно определить расположение грани (к нам или от нас). Если направление взгляда совпадает с вектором (0, 0, 1), то косинус угла между векторами равен nz, и если nz < 0 - грань видна. Стоит отметить, что направление нормали зависит от направления обхода точек полигона - по часовой стрелке или против - и поэтому для получения единой картины все полигоны сцены следует задавать одинаково, иначе возможны неприятные артефакты, например «выпадение» отдельных полигонов.

3.3 Закраска методом Гуро

Если при построении полигональной поверхности для каждой грани используется по одной нормали, то модель освещения создает изображение, состоящее из отдельных многоугольников. Методом Гуро можно получить сглаженное изображение. Для того чтобы изобразить объект методом построчного сканирования, нужно в соответствии с моделью освещения рассчитать интенсивность каждого пиксела вдоль сканирующей строки. Нормали к поверхности аппроксимируются в вершинах многоугольников так, как описано в предыдущем разделе. Однако сканирующая строка не обязательно проходит через вершины многоугольника. При закраске Гуро сначала определяется интенсивность вершин многоугольника, а затем с помощью билинейной интерполяции вычисляется интенсивность каждого пиксела на сканирующей строке.

Построенная таким образом модель выводится на экран достаточно медленно.Пример закраски Гуро можно увидеть на Рисунке 3.

Листинг 5. Метод гуро.

public void PaintGuro(Bitmap bmp, Polygon P)

{

int topY = P.V[0].s.Y;

int downY = P.V[0].s.Y;

foreach (Vertex Vi in P.V)

{

Vi.NormalVertex();

Vi.I = KGiG_Methods.cosAoB(Vi.N, VLight);

if (Vi.I < 0) Vi.I = 0;

if (Vi.s.Y > downY) downY = Vi.s.Y;

if (Vi.s.Y < topY) topY = Vi.s.Y;

}

for (int y = topY; y <= downY; y++)

{

Vertex[] ABCD = CrossBorders(y, P);

if (ABCD != null)

{

double u = ((double)(y - ABCD[0].s.Y)) / (ABCD[1].s.Y - ABCD[0].s.Y);

int x1 = (int)(u * ABCD[1].s.X + (1 - u) * ABCD[0].s.X);

double Iq = u * ABCD[1].I + (1 - u) * ABCD[0].I;

u = ((double)(y - ABCD[2].s.Y)) / (ABCD[3].s.Y - ABCD[2].s.Y);

int x2 = (int)(u * (ABCD[3].s.X - ABCD[2].s.X) + ABCD[2].s.X);

double Ir = u * ABCD[3].I + (1 - u) * ABCD[2].I;

if (x1 > x2) { int xt = x1; x1 = x2; x2 = xt; double It = Iq; Iq = Ir; Ir = It; }

for (int x = x1; x < x2; x++)

{

u = ((double)(x - x1)) / (x2 - x1);

double Ip = u * Ir + (1 - u) * Iq;

Color col = Color.FromArgb((byte)(P.col.R * Ip),

(byte)(P.col.G * Ip),

(byte)(P.col.B * Ip));

bmp.SetPixel(x, y, col);

}

}

}

}

Рисунок 3

4 ТЕСТИРОВАНИЕ

В ходе работы была построена трехмерная модель конуса, реализована закраска методом Гуро, фигуру можно посмотреть в любом ракурсу.

Рисунок 5.

Приложение

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using KGiG;

namespace WindowsFormsApplication4

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

public class Polygon

{

public List<Vertex> V = new List<Vertex>();

public double avrZ;

public Color col;

public Vector3D n;

public bool visible;

public Polygon(Color acol, params Vertex[] Vertexes)

{

double sum = 0;

foreach (Vertex Vi in Vertexes)

{

Vi.LP.Add(this);

V.Add(Vi);

sum += Vi.v.z;

}

avrZ = sum / V.Count;

col = acol;

ComputeNormal();

}

public Polygon(Color acol, Vertex[] Vertexes, int Start, int Count, bool Order)

{

double sum = 0; int si = Start;
int fi = Start + Count -1;

if (Order)

for (int i = si; i < fi + 1; i++)

{

Vertexes[fi - i].LP.Add(this);

V.Add(Vertexes[fi - i]);

sum += Vertexes[fi - i].v.z;

}

else

for (int i = si; i < fi + 1; i++)

{

Vertexes[i].LP.Add(this);

V.Add(Vertexes[i]);

sum += Vertexes[i].v.z;

}

avrZ = sum / V.Count;

col = acol;

ComputeNormal();

}

public void Paint(Graphics gr, Pen pn, Color acol)

{

List<Point> PS = new List<Point>();

foreach (Vertex Vi in V) PS.Add(Vi.s);

gr.FillPolygon(new SolidBrush(acol), PS.ToArray());

gr.DrawPolygon(pn, PS.ToArray() );

}

public void ComputeNormal()

{

Vertex a = V[0];

Vertex b = V[1];

Vertex c = V[2];

double nx = a.v.y * (b.v.z - c.v.z) + b.v.y * (c.v.z - a.v.z) + c.v.y * (a.v.z - b.v.z);

double ny = a.v.z * (b.v.x - c.v.x) + b.v.z * (c.v.x - a.v.x) + c.v.z * (a.v.x - b.v.x);

double nz = a.v.x * (b.v.y - c.v.y) + b.v.x * (c.v.y - a.v.y) + c.v.x * (a.v.y - b.v.y);

double d = 1 / Math.Sqrt(nx * nx + ny * ny + nz * nz);

n = new Vector3D(nx * d, ny * d, nz * d);

double nd = -(a.v.x * (b.v.y * c.v.z - c.v.y * b.v.z) +

b.v.x * (c.v.y * a.v.z - a.v.y * c.v.z) +

c.v.x * (a.v.y * b.v.z - b.v.y * a.v.z)) * d;

double snz = a.s.X * (b.s.Y - c.s.Y) +

b.s.X * (c.s.Y - a.s.Y) +

c.s.X * (a.s.Y - b.s.Y);

visible = snz < 0 ? true : false;

}

}

public class Vertex

{

public Vector3D v;

public Vector3D N;

public double I;

public List<Polygon> LP = new List<Polygon>();

public Point s;

public Vertex(double wx, double wy, double wz)

{

v.x = wx;

v.y = wy;

v.z = wz;

}

public void ScreenTrans(int d, int Ro, int xc, int yc)

{

if ((d != 0) && (v.z + Ro != 0))

{

s.X = (int)(d * v.x / (v.z + Ro)) + xc;

s.Y = (int)(d * v.y / (v.z + Ro)) + yc;

}

}

public void NormalVertex()

{

foreach (Polygon Pi in LP)

{

N += Pi.n;

}

N.normalize();

}

}

Bitmap bmp; Graphics g; const int NC = 40;

Vertex[] mv = new Vertex[NC+1]; Polygon[] mp = new Polygon[NC+1]; Quaternion QRot = new Quaternion(new Vector3D(1, 1, 0), Math.PI / 4);

Vector3D VLight = new Vector3D(0, 0, -1); int d = 600;

int Ro = 500;

void DefineCube()

{

mv[0] = new Vertex(100, 100, 100);

mv[1] = new Vertex(100, -100, 100);

mv[2] = new Vertex(-100, -100, 100);

mv[3] = new Vertex(-100, 100, 100);

mv[4] = new Vertex(100, 100, -100);

mv[5] = new Vertex(100, -100, -100);

mv[6] = new Vertex(-100, -100, -100);

mv[7] = new Vertex(-100, 100, -100);

mv[8] = new Vertex(0, 1, 0);

}

void DefineCilinder()

{

double R = 70;

double da = 2 * Math.PI / NC;

for (int i = 0; i < NC; i++)

{

double x = R * Math.Cos( i * da);

double y = R * Math.Sin( i * da);

mv[i] = new Vertex(x, y, -100);

}

mv[ NC] = new Vertex(0, 0, 100);

for (int i = 0; i < NC; i++)

{

mp[i] = new Polygon(Color.Blue, mv[i],mv[(i+1)%NC], mv[NC]);

}

mp[NC] = new Polygon(Color.Red, mv, NC, NC, true);

//mp[NC+1] = new Polygon(Color.Green, mv, NC, NC, false);

}

void DefineСonus()

{

double R = 70;

double da = 2 * Math.PI / NC;

for (int i = 0; i < NC; i++)

{

double x = R * Math.Cos(i * da);

double y = R * Math.Sin(i * da);

mv[i] = new Vertex(x, y, -100);

mv[i + NC] = new Vertex(x, y, 100);

}

for (int i = 0; i < NC - 1; i++)

{

mp[i] = new Polygon(Color.Blue, mv[i], mv[i + 1], mv[i + NC + 1], mv[i + NC]);

}

mp[NC - 1] = new Polygon(Color.Red, mv[NC - 1], mv[0], mv[NC], mv[NC * 2 - 1]);

mp[NC] = new Polygon(Color.Blue, mv, 0, NC, true);

mp[NC + 1] = new Polygon(Color.Blue, mv, NC, NC, false);

}

void DefineCubePolygons()

{

mp[0] = new Polygon(Color.Blue, mv[3], mv[2], mv[1], mv[0]);

mp[1] = new Polygon(Color.Red, mv[4], mv[5], mv[6], mv[7]);

mp[2] = new Polygon(Color.Green, mv[0], mv[1], mv[5], mv[4]);

mp[3] = new Polygon(Color.Cyan, mv[1], mv[2], mv[6], mv[5]);

mp[4] = new Polygon(Color.Cornsilk, mv[2], mv[3], mv[7], mv[6]);

mp[5] = new Polygon(Color.BurlyWood, mv[3], mv[0], mv[4], mv[7]);

}

void ViewTrans()

{

for (int i = 0; i < mv.Length; i++)

{

mv[i].v = KGiG_Methods.RotateVector(mv[i].v, QRot);

mv[i].ScreenTrans(d, Ro, pictureBox1.Width / 2, pictureBox1.Height / 2);

}

QRot = new Quaternion(1, new Vector3D());

}

void SortPolygons()

{

for (int j = 0; j < mp.Length; j++)

for (int i = 0; i < mp.Length-1; i++)

{

if ( mp[i].avrZ < mp[i + 1].avrZ )

{

Polygon temp = mp[i];

mp[i] = mp[i + 1];

mp[i + 1] = temp;

}

}

}

public Vertex[] CrossBorders(int lineY, Polygon P)

{

Vertex[] res = null;

Vertex topV = null;

Vertex downV = null;

Vertex topV1 = null;

Vertex downV1 = null;

for (int i = 0; i < P.V.Count; i++)

{

int j = (i + 1) % P.V.Count;

if (P.V[i].s.Y != P.V[j].s.Y)

{

if (P.V[i].s.Y < P.V[j].s.Y)

{

topV = P.V[i];

downV = P.V[j];

}

else

{

topV = P.V[j];

downV = P.V[i];

}

if ((lineY >= topV.s.Y) && (lineY < downV.s.Y))

{

if (topV1 == null)

{

topV1 = topV;

downV1 = downV;

}

else

{

res = new Vertex[] { topV1, downV1, topV, downV };

break;

}

}

}

}

return res;

}

public void PaintPhong(Bitmap bmp, Polygon P)

{

int topY = P.V[0].s.Y;

int downY = P.V[0].s.Y;

foreach (Vertex Vi in P.V)

{

Vi.NormalVertex();

if (Vi.s.Y > downY) downY = Vi.s.Y;

if (Vi.s.Y < topY) topY = Vi.s.Y;

}

for (int y = topY; y <= downY; y++)

{

Vertex[] ABCD = CrossBorders(y, P);

if (ABCD != null)

{

float u = ((float)(y - ABCD[0].s.Y)) / (ABCD[1].s.Y - ABCD[0].s.Y);

int x1 = (int)(u * ABCD[1].s.X + (1 - u) * ABCD[0].s.X);

Vector3D NQ = u * ABCD[1].N + (1 - u) * ABCD[0].N;

u = ((float)(y - ABCD[2].s.Y)) / (ABCD[3].s.Y - ABCD[2].s.Y);

int x2 = (int)(u * (ABCD[3].s.X - ABCD[2].s.X) + ABCD[2].s.X);

Vector3D NR = u * ABCD[3].N + (1 - u) * ABCD[2].N;

if (x1 > x2) { int xt = x1; x1 = x2; x2 = xt; Vector3D NT = NQ; NQ = NR; NR = NT; }

for (int x = x1; x < x2; x++)

{

u = ((float)(x - x1)) / (x2 - x1);

Vector3D NP = u * NR + (1 - u) * NQ;

double Ipm = Math.Pow(KGiG_Methods.cosAoB(NP, VLight), 4);

if (Ipm < 0) Ipm = 0;

double Ip = Ipm * 0.8 + 0.4;

int CR = (int)(P.col.R * Ip);

int CG = (int)(P.col.G * Ip);

int CB = (int)(P.col.B * Ip);

if (CR > 255) CR = 255;

if (CG > 255) CG = 255;

if (CB > 255) CB = 255;

Color colP = Color.FromArgb(CR, CG, CB);

bmp.SetPixel(x, y, colP);

}

}

}

}

public void PaintGuro(Bitmap bmp, Polygon P)

{

int topY = P.V[0].s.Y;

int downY = P.V[0].s.Y;

foreach (Vertex Vi in P.V)

{

Vi.NormalVertex();

Vi.I = KGiG_Methods.cosAoB(Vi.N, VLight);

if (Vi.I < 0) Vi.I = 0;

if (Vi.s.Y > downY) downY = Vi.s.Y;

if (Vi.s.Y < topY) topY = Vi.s.Y;

}

for (int y = topY; y <= downY; y++)

{

Vertex[] ABCD = CrossBorders(y, P);

if (ABCD != null)

{

double u = ((double)(y - ABCD[0].s.Y)) / (ABCD[1].s.Y - ABCD[0].s.Y);

int x1 = (int)(u * ABCD[1].s.X + (1 - u) * ABCD[0].s.X);

double Iq = u * ABCD[1].I + (1 - u) * ABCD[0].I;

u = ((double)(y - ABCD[2].s.Y)) / (ABCD[3].s.Y - ABCD[2].s.Y);

int x2 = (int)(u * (ABCD[3].s.X - ABCD[2].s.X) + ABCD[2].s.X);

double Ir = u * ABCD[3].I + (1 - u) * ABCD[2].I;

if (x1 > x2) { int xt = x1; x1 = x2; x2 = xt; double It = Iq; Iq = Ir; Ir = It; }

for (int x = x1; x < x2; x++)

{

u = ((double)(x - x1)) / (x2 - x1);

double Ip = u * Ir + (1 - u) * Iq;

Color col = Color.FromArgb((byte)(P.col.R * Ip),

(byte)(P.col.G * Ip),

(byte)(P.col.B * Ip));

bmp.SetPixel(x, y, col);

}

}

}

}

void Paint3DObject()

{

//SortPolygons();

for (int i = 0; i < mp.Length; i++)

{

mp[i].ComputeNormal();

if (mp[i].visible)

{

//double alfa = Math.Abs( KGiG_Methods.cosAoB(mp[i].n, VLight));

//Color newCol = Color.FromArgb( (int)(alfa * mp[i].col.R),

// (int)(alfa * mp[i].col.G),

// (int)(alfa * mp[i].col.B) );

//mp[i].Paint(g, new Pen(Brushes.Black, 1), newCol);

if (i > NC )

{

double alfa = Math.Abs( KGiG_Methods.cosAoB(mp[i].n, VLight));

Color newCol = Color.FromArgb( (int)(alfa * mp[i].col.R),

(int)(alfa * mp[i].col.G),

(int)(alfa * mp[i].col.B) );

mp[i].Paint(g, new Pen(Brushes.Black, 1), newCol);

}

else

//PaintGuro(bmp, mp[i]);

PaintPhong(bmp, mp[i]);

}

}

}

void RePaint()

{

g.Clear(Form1.DefaultBackColor);

ViewTrans();

Paint3DObject();

pictureBox1.Image = bmp;

}

private void Form1_Shown(object sender, EventArgs e)

{

bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);

g = Graphics.FromImage(bmp);

g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

DefineCilinder();

//DefineCube();

//DefineCubePolygons();

RePaint();

}

private void Form1_KeyDown(object sender, KeyEventArgs e)

{

if (e.KeyCode == Keys.Left) QRot = new Quaternion(new Vector3D(0, 1.0, 0), Math.PI / 64);

if (e.KeyCode == Keys.Right) QRot = new Quaternion(new Vector3D(0, 1.0, 0), -Math.PI / 64);

if (e.KeyCode == Keys.Up) QRot = new Quaternion(new Vector3D(1.0, 0, 0), -Math.PI / 64);

if (e.KeyCode == Keys.Down) QRot = new Quaternion(new Vector3D(1.0, 0, 0), Math.PI / 64);

RePaint();

}

int x = 0;

int y = 0;

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)

{

x = e.X;

y = e.Y;

pictureBox1.Cursor = System.Windows.Forms.Cursors.Hand;

}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)

{

if (e.Button == System.Windows.Forms.MouseButtons.Left)

{

int dx = e.X - x;

int dy = e.Y - y;

QRot = new Quaternion(new Vector3D(dy, -dx, 0), Math.PI / 128);

x = e.X;

y = e.Y;

RePaint();

}

if (e.Button == System.Windows.Forms.MouseButtons.Right)

{

int dx = e.X - x;

QRot = new Quaternion(mv[8].v, -dx * Math.PI / 256);

x = e.X;

RePaint();

}

}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)

{

pictureBox1.Cursor = System.Windows.Forms.Cursors.Default;

}

}

}

Размещено на Allbest.ru

...

Подобные документы

  • Моделирование непрерывной системы контроля на основе матричной модели объекта наблюдения. Нахождение передаточной функции формирующего фильтра входного процесса. Построение графика зависимости координаты и скорости от времени, фазовой траектории системы.

    курсовая работа [1,5 M], добавлен 25.12.2013

  • Изучение свойств геометрических объектов при помощи алгебраических методов. Основные операции над векторами. Умножение вектора на отрицательное число. Скалярное произведение векторов. Нахождение угла между векторами. Нахождение координат вектора.

    контрольная работа [56,3 K], добавлен 03.12.2014

  • Анализ динамических процессов в системе на основе использования построенной аналитической модели. Моделирование с использованием пакета расширения Symbolic Math Tolbox. Построение модели в виде системы дифференциальных уравнений, записанных в форме Коши.

    курсовая работа [863,4 K], добавлен 21.06.2015

  • Нахождение экстремумов функций методом множителей Лагранжа. Выражение расширенной целевой функции. Схема алгоритма численного решения задачи методом штрафных функций в сочетании с методом безусловной минимизации. Построение линий ограничений.

    курсовая работа [259,9 K], добавлен 04.05.2011

  • Решение системы линейных уравнений методом Якоби вручную и на Бейсике. Построение интерполяционного многочлена Ньютона с помощью Excel. Получение аппроксимирующей функции методом наименьших квадратов. Построение кубического сплайна по шести точкам.

    курсовая работа [304,9 K], добавлен 07.09.2012

  • Математические модели технических объектов и методы для их реализации. Анализ электрических процессов в цепи второго порядка с использованием систем компьютерной математики MathCAD и Scilab. Математические модели и моделирование технического объекта.

    курсовая работа [565,7 K], добавлен 08.03.2016

  • Разработка методики оценки состояния гидротехнического объекта, подверженного воздействию наводнений различной природы, с использованием теории нечетких множеств. Моделирование возможного риска с целью решения задачи зонирования прибрежной территории.

    курсовая работа [734,2 K], добавлен 23.07.2011

  • Различные способы задания прямой на плоскости и в пространстве. Конструктивные задачи трехмерного пространства. Изображения фигур и их правильное восприятие и чтение. Использование в геометрии монографического и математического метода исследования.

    курсовая работа [1,1 M], добавлен 22.09.2014

  • Линейные операции над векторами. Скалярное произведение двух векторов. Векторное произведение векторов. Графическое решение систем неравенств. Построение графиков функций с помощью геометрических преобразований. Простейшие геометрические преобразования.

    методичка [2,0 M], добавлен 15.06.2015

  • Теоретические положения симплекс-метода и постоптимального анализа. Построение математической модели задачи. Нахождение ценностей ресурсов. Определение относительных и абсолютных диапазонов изменения уровней запасов дефицитных и недефицитных ресурсов.

    курсовая работа [86,7 K], добавлен 19.11.2010

  • Элементы аналитической геометрии и линейной алгебры. Методы построения графика функции. Предел и непрерывность функции. Дифференциальное исчисление функции одной переменной. Определители и системы уравнений. Построение прямой и плоскости в пространстве.

    методичка [1,0 M], добавлен 24.08.2009

  • Задача на вычисление скалярного произведения векторов. Нахождение модуля векторного произведения. Проверка коллинеарности и ортогональности. Составление канонического уравнения эллипса, гиперболы, параболы. Нахождение косинуса угла между его нормалями.

    контрольная работа [102,5 K], добавлен 04.12.2013

  • Понятие нечеткого множества и свойства его элементов. Определение логических операций: отрицания, конъюнкции, дизъюнкции. Основные этапы нечеткого вывода, метод центра тяжести. Оценка состояния повреждения объекта на основе теории нечетких множеств.

    курсовая работа [316,8 K], добавлен 22.07.2011

  • Возникновение геометрии как науки о формах, размерах и границах частей пространства, которые в нем занимают вещественные тела. Появление геометрии в Греции к концу VII в. до н. э. Теорема Пифагора и развитие методов аналитической геометрии Гаусса.

    реферат [38,5 K], добавлен 16.01.2010

  • Разработка проекта системы автоматического управления тележкой, движущейся в боковой плоскости. Описание и анализ непрерывной системы, создание ее математических моделей в пространстве состояний и модели "вход-выход". Построение графиков реакций объекта.

    курсовая работа [1,7 M], добавлен 25.12.2010

  • Методика нахождения различных решений геометрических задач на построение. Выбор и применение методов геометрических преобразований: параллельного переноса, симметрии, поворота (вращения), подобия, инверсии в зависимости от формы и свойств базовой фигуры.

    курсовая работа [6,4 M], добавлен 13.08.2011

  • Определение положения точки в пространстве. Правая декартова (или прямоугольная) система координат. Способы измерения дуг. Определение координат точки в пространстве. Определение окружности и ее радиуса. Построение сферической системы координат.

    контрольная работа [59,3 K], добавлен 13.05.2009

  • Решение дифференциального уравнения методом Адамса. Нахождение параметров синтезирования регулятора САУ численным методом. Решение дифференциального уравнения неявным численным методом. Анализ системы с использованием критериев Михайлова и Гурвица.

    курсовая работа [398,2 K], добавлен 13.07.2010

  • Метод планирования второго порядка на примере В3-плана. Получение и исследование математической модели объекта в виде полинома второго порядка. Статистический анализ полученного уравнения и построение поверхностей отклика. Расчет коэффициентов регрессии.

    курсовая работа [128,4 K], добавлен 18.11.2010

  • Основные положения теории математического моделирования. Структура математической модели. Линейные и нелинейные деформационные процессы в твердых телах. Методика исследования математической модели сваи сложной конфигурации методом конечных элементов.

    курсовая работа [997,2 K], добавлен 21.01.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.