Компьютерная графика средствами Windows Forms

Двумерная графика: понятие и принципы формирования, правила преобразования координат. Сущность и работа с методом сканирующей строки. Параллельная и центральная проекция: сравнительная характеристика, главные условия и возможности использования.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 11.04.2015
Размер файла 194,2 K

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

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

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

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

Введение

двумерный графика проекция координата

Существует немало языков программирования, но лишь немногие из них действительно хороши. Хороший язык программирования должен быть одновременно эффективным и гибким, а его синтаксис - кратким, но ясным. Он должен облегчать создание правильного кода, не мешая делать это, а также поддерживать самые современные возможности программирования, но не ультрамодные тенденции, заводящие в тупик. И наконец, хороший язык программирования должен обладать еще одним, едва уловимым качеством: вызывать у нас такое ощущение, будто мы находимся в своей стихии, когда пользуемся им. Именно таким языком и является С# [1].

Данная работа посвящена изучению некоторых разделов интерактивной компьютерной графики средствами C#.

1. Двумерная графика

Задача: Написать программу, которая строит график функции на отрезке [a, b], заданной явно. Подобрать отрезок [a, b], который содержит только одну точку разрыва [2].

Решение:

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. Drawing. Drawing2D;

namespace WindowsFormsApplication5

{

public partial class Form1: Form

{

public Form1 ()

{

InitializeComponent();

}

protected override void OnPaint (PaintEventArgs e)

{

base. OnPaint(e);

Graphics g = e. Graphics;

float xmin, xmax, ymin, ymax, x, y, h;

int r = 3;

double eps = 0.001;

xmin = 1; xmax = 6;

h = (xmax - xmin) / 500;

ymin = F(xmin);

ymax = ymin;

x = xmin + h;

for (x = xmin; x < r-eps; x = x + h)

{

y = F(x);

if (y < ymin) ymin = y;

if (y > ymax) ymax = y;

}

for (x = r + h; x <= xmax; x = x + h)

{

y = F(x);

if (y < ymin) ymin = y;

if (y > ymax) ymax = y;

}

float dx = (xmax - xmin) * 0.03f;

float dy = (ymax - ymin) * 0.03f;

float ax = ClientSize. Width / (xmax - xmin + 2 * dx);

float ay = - ClientSize. Height / (ymax - ymin + 2 * dy);

float bx = - ax * (xmin - dx);

float by = - ay * (ymax + dy);

g. Transform = new Matrix (ax, 0, 0, ay, bx, by);

float hf, wf, a, b, c, d;

float asm = (xmax - xmin) / (ymax - ymin);

float asf = (float) ClientSize. Width / (float) ClientSize. Height;

if (asm > asf)

{

wf = ClientSize. Width;

hf = (ymax - ymin) * wf / (xmax - xmin);

a = 0;

b = (ClientSize. Height - hf) / 2;

c = ClientSize. Width;

d = (ClientSize. Height + hf) / 2;

}

else

{

hf = ClientSize. Height;

wf = (xmax - xmin) * hf / (ymax - ymin);

a = (ClientSize. Width - wf) / 2;

b = 0;

c = (ClientSize. Width + wf) / 2;

d = ClientSize. Height;

}

ax = (c - a) / (xmax - xmin + 2 * dx);

ay = (b - d) / (ymax - ymin + 2 * dy);

bx = a - ax * (xmin - dx);

by = b - ay * (ymax + dy);

float hline = (xmax - xmin) * 0.001f;

Pen blackPen = new Pen (Color. Black, hline);

Pen bluePen = new Pen (Color. Blue, hline);

x = xmin;

g. DrawLine (bluePen, xmin, 0, xmax, 0);

g. DrawLine (bluePen, 0, ymin, 0, ymax);

while (x <= r - h)

{

g. DrawLine (blackPen, x, F(x), x + h, F (x + h));

x = x + h;

}

x = r + h;

while (x <= xmax)

{

g. DrawLine (blackPen, x, F(x), x + h, F (x + h));

x = x + h;

}

}

private float F (float x)

{

return x / (x * x - 9);

}

private void Form1_Resize (object sender, EventArgs e)

{

Invalidate();

}

}

}

Рисунок 1.1 Реализация программы, которая строит двумерный график функции, заданной явно, с одной точкой разрыва

Задача: Написать программу, которая строит график функции на отрезке [a, b], заданной параметрически.

Решение:

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. Drawing;

using System. Drawing. Drawing2D;

namespace WindowsFormsApplication1

{

public partial class Form1: Form

{

public Form1 ()

{

InitializeComponent();

}

protected override void OnPaint (PaintEventArgs e)

{

base. OnPaint(e);

Graphics g = e. Graphics;

float xmin, xmax, ymin, ymax, x, t, y, h;

float tmin = -5, tmax = 5;

xmin = F1 (tmin); xmax = F1 (tmax);

h = (tmax - tmin) / 500;

ymin = F2 (tmin);

ymax = ymin;

t = tmin + h;

for (t = tmin; t < tmax; t = t + h)

{

x = F1 (t);

if (x < xmin) xmin = x;

if (x > xmax) xmax = x;

y = F2 (t);

if (y < ymin) ymin = y;

if (y > ymax) ymax = y;

}

float dx = (xmax - xmin) * 0.03f;

float dy = (ymax - ymin) * 0.03f;

float ax = ClientSize. Width / (xmax - xmin + 2 * dx);

float ay = - ClientSize. Height / (ymax - ymin + 2 * dy);

float bx = - ax * (xmin - dx);

float by = - ay * (ymax + dy);

float hf, wf, a, b, c, d;

float asm = (xmax - xmin) / (ymax - ymin);

float asf = (float) ClientSize. Width / (float) ClientSize. Height;

if (asm > asf)

{

wf = ClientSize. Width;

hf = (ymax - ymin) * wf / (xmax - xmin);

a = 0;

b = (ClientSize. Height - hf) / 2;

c = ClientSize. Width;

d = (ClientSize. Height + hf) / 2;

}

else

{

hf = ClientSize. Height;

wf = (xmax - xmin) * hf / (ymax - ymin);

a = (ClientSize. Width - wf) / 2;

b = 0;

c = (ClientSize. Width + wf) / 2;

d = ClientSize. Height;

}

ax = (c - a) / (xmax - xmin + 2 * dx);

ay = (b - d) / (ymax - ymin + 2 * dy);

bx = a - ax * (xmin - dx);

by = b - ay * (ymax + dy);

g. Transform = new Matrix (ax, 0, 0, ay, bx, by);

float hline = (xmax - xmin) * 0.001f;

Pen blackPen = new Pen (Color. Black, hline);

Pen bluePen = new Pen (Color. Blue, hline);

t = tmin;

g. DrawLine (bluePen, xmin, 0, xmax, 0);

g. DrawLine (bluePen, 0, ymin, 0, ymax);

while (t <= tmax)

{

g. DrawLine (blackPen, F1 (t), F2 (t), F1 (t + h), F2 (t + h));

t = t + h;

}

}

private float F1 (float x)

{

return (float) (6 * Math. Cos(x) + 2 * Math. Cos (6 * x));

}

private float F2 (float x)

{

return (float) (6 * Math. Sin(x) - 2 * Math. Sin (6 * x));

}

private void Form1_Resize (object sender, EventArgs e)

{

Invalidate();

}

}

}

Рисунок 1.2 Реализация программы, которая строит двумерный график функции, заданной параметрически

2. Преобразования двумерных координат

Задача: Написать программу, демонстрирующую преобразование двумерных координат (перенос, поворот и масштабирование). Вывести график функции до преобразования и после него в одном окне [2].

Решение:

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. Drawing;

using System. Drawing. Drawing2D;

namespace WindowsFormsApplication1

{

public partial class Form1: Form

{

public Form1 ()

{

InitializeComponent();

}

public float transX (float x, float y, float Alfa, float d, float s)

{

return (float) ((s * x * Math. Cos(Alfa) + s * y * Math. Sin(Alfa) + d));

}

public float transY (float x, float y, float Alfa, float d, float s)

{

return (float) (-s * x * Math. Sin(Alfa) + s * y * Math. Cos(Alfa) + d);

}

protected override void OnPaint (PaintEventArgs e)

{

base. OnPaint(e);

Graphics g = e. Graphics;

float fi, fimin, fimax, xmin, xmax, ymin, ymax, x, y, h, x2, y2;

float tx, ty, Alfa, s;

s = 2;

tx = 10; ty = 7; Alfa = (float) (Math.PI) / 6;

fimin = 0; fimax = (float) (4 * (Math.PI));

h = (fimax - fimin) / 100;

xmin = (float) (F(fimin) * Math. Cos(fimin));

ymin = (float) (F(fimin) * Math. Sin(fimin));

xmax = xmin;

ymax = ymin;

fi = fimin + h;

while (fi < fimax)

{

x = (float) (F(fi) * Math. Cos(fi));

if (x < xmin) xmin = x;

if (x > xmax) xmax = x;

y = (float) (F(fi) * Math. Sin(fi));

if (y < ymin) ymin = y;

if (y > ymax) ymax = y;

x2 = transX (x, y, Alfa, tx, s);

if (x2 < xmin) xmin = x2;

if (x2 > xmax) xmax = x2;

y2 = transY (x, y, Alfa, ty, s);

if (y2 < ymin) ymin = y2;

if (y2 > ymax) ymax = y2;

fi = fi + h;

}

float dx = (xmax - xmin) * 0.03f;

float dy = (ymax - ymin) * 0.03f;

float ax = ClientSize. Width / (xmax - xmin + 2 * dx);

float ay = - ClientSize. Height / (ymax - ymin + 2 * dy);

float bx = - ax * (xmin - dx);

float by = - ay * (ymax + dy);

float hf, wf, a, b, c, d;

float asm = (xmax - xmin) / (ymax - ymin);

float asf = (float) ClientSize. Width / (float) ClientSize. Height;

if (asm > asf)

{

wf = ClientSize. Width;

hf = (ymax - ymin) * wf / (xmax - xmin);

a = 0;

b = (ClientSize. Height - hf) / 2;

c = ClientSize. Width;

d = (ClientSize. Height + hf) / 2;

}

else

{

hf = ClientSize. Height;

wf = (xmax - xmin) * hf / (ymax - ymin);

a = (ClientSize. Width - wf) / 2;

b = 0;

c = (ClientSize. Width + wf) / 2;

d = ClientSize. Height;

}

ax = (c - a) / (xmax - xmin + 2 * dx);

ay = (b - d) / (ymax - ymin + 2 * dy);

bx = a - ax * (xmin - dx);

by = b - ay * (ymax + dy);

g. Transform = new Matrix (ax, 0, 0, ay, bx, by);

float hline = (xmax - xmin) * 0.001f;

Pen blackPen = new Pen (Color. Black, hline);

Pen bluePen = new Pen (Color. Blue, hline);

g. DrawLine (bluePen, xmin, 0, xmax, 0);

g. DrawLine (bluePen, 0, ymin, 0, ymax);

fi = fimin;

while (fi <= fimax)

{

g. DrawLine (blackPen, (float) (F(fi) * Math. Cos(fi)), (float) (F(fi) * Math. Sin(fi)), (float) (F (fi + h) * Math. Cos (fi + h)), (float) (F (fi + h) * Math. Sin (fi + h)));

fi = fi + h;

}

fi = fimin;

while (fi <= fimax)

{

x = (float) (F(fi) * Math. Cos(fi));

y = (float) (F(fi) * Math. Sin(fi));

x2 = (float) (F (fi + h) * Math. Cos (fi + h));

y2 = (float) (F (fi + h) * Math. Sin (fi + h));

g. DrawLine (blackPen, transX (x, y, Alfa, tx, s), transY (x, y, Alfa, ty, s), transX (x2, y2, Alfa, tx, s), transY (x2, y2, Alfa, ty, s));

fi = fi + h;

}

}

private float F (float fi)

{

return 3 * (1 + (float) (Math. Cos(fi)));

}

private void Form1_Resize (object sender, EventArgs e)

{

Invalidate();

}

}

}

Рисунок 2.1 Реализация программы, демонстрирующей преобразование двумерных координат

3. Метод сканирующей строки

Задача: Разработать алгоритм и написать программу, демонстрирующую метод сканирующей строки для закрашивания треугольных областей [2].

Решение:

Класс:

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

using System. Drawing;

using System. Drawing. Drawing2D;

using System. Collections;

namespace Laba3

{

class FillTriangle

{

public void Fill (Graphics g, int[] x, int[] y, int[] rgb)

{

int maxy, miny;

maxy = y[0];

miny = maxy;

if (y[1] > maxy) maxy = y[1];

if (y[2] > maxy) maxy = y[2];

if (y[1] < miny) miny = y[1];

if (y[2] < miny) miny = y[2];

float t;

ArrayList mas = new ArrayList();

Pen myPen = new Pen (Color. FromArgb (255, rgb[0], rgb[1], rgb[2]));

for (int yt = miny; yt <= maxy; yt++)

{

mas. Clear();

if (y[0]!=y[1])

{

t = (float) (yt-y[1])/(float) (y[0] - y[1]);

if (t>=0 && t<=1)

mas. Insert (0, (int) (t*x[0] + (1-t)*x[1]));

}

{

t = (float) (yt-y[2])/(float) (y[1] - y[2]);

if (t>=0 && t<=1)

mas. Insert (0, (int) (t*x[1] + (1-t)*x[2]));

}

{

t = (float) (yt-y[2])/(float) (y[0] - y[2]);

if (t>=0 && t<=1)

mas. Insert (0, (int) (t*x[0] + (1-t)*x[2]));

}

g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);

if (mas. Count == 3)

{

g. DrawLine (myPen, (int) mas[1], yt, (int) mas[2], yt);

}

}

}

}

}

Форма:

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. Drawing;

using System. Drawing. Drawing2D;

namespace Laba3

{

public partial class Form1: Form

{

private int k = 0;

private int[] x = new int[3];

private int[] y = new int[3];

private int[] rgb = new int[3];

public Form1 ()

{

InitializeComponent();

}

private void Form1_MouseDown (object sender, MouseEventArgs e)

{

if (k <= 2)

{

x[k] = e.X;

y[k] = e.Y;

if (k == 2)

{

rgb[0] = 255;

rgb[2] = 0;

rgb[2] = 0;

Graphics g = Graphics. FromHwnd (this. Handle);

FillTriangle f = new FillTriangle();

f. Fill (g, x, y, rgb);

g. Dispose();

}

k++;

}

else

return;

}

}

}

Рисунок 3.1 Реализация программы, демонстрирующей метод сканирующей строки для закрашивания треугольных областей

4. Параллельная проекция

Задача: Написать программу, которая строит на экране изображение выпуклого трехмерного тела при параллельной проекции. Удалить невидимые грани. Видимые грани закрасить оттенками серого цвета в зависимости от расположения соответствующей грани и источника света. Для закрашивания граней использовать метод сканирующей строки [2].

Решение:

Класс:

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

using System. Drawing;

using System. Collections;

namespace Triangle

{

class FillTriangle

{

public void Fill (Graphics g, int[] x, int[] y, int[] rgb)

{

int maxy, miny;

ArrayList mas = new ArrayList();

float a;

Pen myPen = new Pen (Color. FromArgb (255, rgb[0], rgb[1], rgb[2]));

if (Math. Abs((x[1] - x[0]) * (y[2] - y[0]) - (x[2] - x[0]) * (y[1] - y[0])) <= 0.001)

{

g. DrawLine (myPen, x[0], y[0], x[1], y[1]);

g. DrawLine (myPen, x[1], y[1], x[2], y[2]);

return;

}

maxy = y[0];

miny = maxy;

for (int i = 1; i <= 2; i++)

{

if (y[i] > maxy) maxy = y[i];

if (y[i] < miny) miny = y[i];

}

for (int yt = miny; yt <= maxy; yt++)

{

mas. Clear();

if (y[0]!= y[1])

{

a = (float) (yt - y[1])/(float) (y[0] - y[1]);

if (a >= 0 && a <= 1)

{

mas. Insert (0, (int) (a * x[0] + (1 - a) * x[1]));

}

}

if (y[1]!= y[2])

{

a = (float) (yt - y[2]) / (float) (y[1] - y[2]);

if (a >= 0 && a <= 1)

{

mas. Insert (0, (int) (a * x[1] + (1 - a) * x[2]));

}

}

if (y[0]!= y[2])

{

a = (float) (yt - y[2]) / (float) (y[0] - y[2]);

if (a >= 0 && a <= 1)

{

mas. Insert (0, (int) (a * x[0] + (1 - a) * x[2]));

}

}

if (mas. Count == 3)

{

g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);

g. DrawLine (myPen, (int) mas[1], yt, (int) mas[2], yt);

}

else

g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);

}

}

}

}

Форма:

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. Drawing. Drawing2D;

namespace Lab_4

{

public partial class Form1: Form

{

private double[] xv = {0, 2, 0, 0, 2, 0};

private double[] yv = {0, 0, 2, 0, 0, 2};

private double[] zv = {0, 0, 0, 2, 2, 2};

private double[] xpl = new double[6];

private double[] ypl = new double[6];

private int[] xfrm = new int[6];

private int[] yfrm = new int[6];

private int[,] gran1 = new int [3, 4];

private int[,] gran2 = new int [2, 3];

private double u1x, u1y, u1z, u2x, u2y, u2z, u3x, u3y, u3z;

private double rx, ry, rz;

private double ax, ay, az;

private double sx, sy, sz;

private double r;

private double a, b, c, d;

public Form1 ()

{

InitializeComponent();

}

private void Form1_Load (object sender, EventArgs e)

{

rx = 10; ry = 5; rz = 5;

ax = 1; ay = 1; az = 1;

sx = -5; sy = 1; sz = 5;

r = Math. Sqrt(3);

u3x = ax - rx; u3y = ay - ry; u3z = az - rz;

double t = Math. Sqrt (u3x * u3x + u3y * u3y + u3z * u3z);

u3x = u3x / t; u3y = u3y / t; u3z = u3z / t;

u1x = u3y; u1y = - u3x; u1z = 0;

t = Math. Sqrt (u1x * u1x + u1y * u1y + u1z * u1z);

u1x = u1x / t; u1y = u1y / t; u1z = u1z / t;

u2x = u1y * u3z - u3y * u1z; u2y = u3x * u1z - u1x * u3z; u2z = u1x * u3y - u3x * u1y;

t = Math. Sqrt (u2x * u2x + u2y * u2y + u2z * u2z);

u2x = u2x / t; u2y = u2y / t; u2z = u2z / t;

gran1 [1, 0] = 0; gran1 [1, 1] = 1; gran1 [1, 2] = 4; gran1 [1, 3] = 3;

gran1 [0, 0] = 0; gran1 [0, 1] = 3; gran1 [0, 2] = 5; gran1 [0, 3] = 2;

gran1 [2, 0] = 1; gran1 [2, 1] = 2; gran1 [2, 2] = 5; gran1 [2, 3] = 4;

gran2 [0, 0] = 0; gran2 [0, 1] = 2; gran2 [0, 2] = 1;

gran2 [1, 0] = 3; gran2 [1, 1] = 4; gran2 [1, 2] = 5;

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

{

xpl[i] = px (xv[i], yv[i], zv[i]);

ypl[i] = py (xv[i], yv[i], zv[i]);

}

Ini();

}

private double px (double x, double y, double z)

{

return ((x - rx) * u1x + (y - ry) * u1y + (z - rz) * u1z);

}

private double py (double x, double y, double z)

{

return ((x - rx) * u2x + (y - ry) * u2y + (z - rz) * u2z);

}

private void Ini()

{

double wp, hp;

if (ClientSize. Width >= ClientSize. Height)

{

wp = 2 * r * ClientSize. Width / ClientSize. Height; hp = 2 * r;

}

else

{

wp = 2 * r; hp = 2 * r * ClientSize. Height / ClientSize. Width;

}

a = ClientSize. Width / wp;

b = ClientSize. Width / 2;

c = - ClientSize. Height / hp;

d = ClientSize. Height / 2;

}

protected override void OnPaint (PaintEventArgs e)

{

base. OnPaint(e);

Graphics g=e. Graphics;

g. Clear (Color. White);

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

{

xfrm[i]=fx (xpl[i]);

yfrm[i]=fy (ypl[i]);

}

double bx, by, bz, cx, cy, cz, nx, ny, nz;

int[] rgb=new int[3];

int[] x=new int[3]; int[] y=new int[3];

double cosfi;

Triangle. FillTriangle myFill=new Triangle. FillTriangle();

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

{

bx=xv [gran1 [i, 1]] - xv [gran1 [i, 0]];

by=yv [gran1 [i, 1]] - yv [gran1 [i, 0]];

bz=zv [gran1 [i, 1]] - zv [gran1 [i, 0]];

cx=xv [gran1 [i, 2]] - xv [gran1 [i, 0]];

cy=yv [gran1 [i, 2]] - yv [gran1 [i, 0]];

cz=zv [gran1 [i, 2]] - zv [gran1 [i, 0]];

nx=by*cz-bz*cy;

ny=bz*cx-bx*cz;

nz=bx*cy-by*cx;

if (nx*u3x+ny*u3y+nz*u3z>0)

{

bx=xv [gran1 [i, 0]]; by=yv [gran1 [i, 0]]; bz=zv [gran1 [i, 0]];

for (int j=1; j<=3; j++)

{

bx+=xv [gran1 [i, j]]; by+=yv [gran1 [i, j]]; bz+=zv [gran1 [i, j]];

}

bx=bx/4; by=by/4; bz=bz/4;

cx=bx-sx; cy=by-sy; cz=bz-sz;

cosfi=(nx*cx+ny*cy+nz*cz)/ (Math. Sqrt (nx*nx+ny*ny+nz*nz)*Math. Sqrt (cx*cx+cy*cy+cz*cz));

rgb[0]=(int) (-255*cosfi/2+255/2);

rgb[1]=rgb[0]; rgb[2]=rgb[0];

x[0]=xfrm [gran1 [i, 0]]; y[0]=yfrm [gran1 [i, 0]];

x[1]=xfrm [gran1 [i, 1]]; y[1]=yfrm [gran1 [i, 1]];

x[2]=xfrm [gran1 [i, 2]]; y[2]=yfrm [gran1 [i, 2]];

myFill. Fill (g, x, y, rgb);

x[0]=xfrm [gran1 [i, 0]]; y[0]=yfrm [gran1 [i, 0]];

x[1]=xfrm [gran1 [i, 2]]; y[1]=yfrm [gran1 [i, 2]];

x[2]=xfrm [gran1 [i, 3]]; y[2]=yfrm [gran1 [i, 3]];

myFill. Fill (g, x, y, rgb);

}

}

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

{

bx = xv [gran2 [i, 1]] - xv [gran2 [i, 0]];

by = yv [gran2 [i, 1]] - yv [gran2 [i, 0]];

bz = zv [gran2 [i, 1]] - zv [gran2 [i, 0]];

cx = xv [gran2 [i, 2]] - xv [gran2 [i, 0]];

cy = yv [gran2 [i, 2]] - yv [gran2 [i, 0]];

cz = zv [gran2 [i, 2]] - zv [gran2 [i, 0]];

nx = by * cz - bz * cy;

ny = bz * cx - bx * cz;

nz = bx * cy - by * cx;

if (nx * u3x + ny * u3y + nz * u3z > 0)

{

bx = xv [gran2 [i, 0]]; by = yv [gran2 [i, 0]]; bz = zv [gran2 [i, 0]];

for (int j = 1; j <= 2; j++)

{

bx += xv [gran2 [i, j]]; by += yv [gran2 [i, j]]; bz += zv [gran2 [i, j]];

}

bx = bx / 3; by = by / 3; bz = bz / 3;

cx = bx - sx; cy = by - sy; cz = bz - sz;

cosfi = (nx * cx + ny * cy + nz * cz) / (Math. Sqrt (nx * nx + ny * ny + nz * nz) * Math. Sqrt (cx * cx + cy * cy + cz * cz));

rgb[0] = (int) (-255 * cosfi/2+255/2);

rgb[1] = rgb[0]; rgb[2] = rgb[0];

x[0] = xfrm [gran2 [i, 0]]; y[0] = yfrm [gran2 [i, 0]];

x[1] = xfrm [gran2 [i, 1]]; y[1] = yfrm [gran2 [i, 1]];

x[2] = xfrm [gran2 [i, 2]]; y[2] = yfrm [gran2 [i, 2]];

myFill. Fill (g, x, y, rgb);

x[0] = xfrm [gran2 [i, 0]]; y[0] = yfrm [gran2 [i, 0]];

x[1] = xfrm [gran2 [i, 1]]; y[1] = yfrm [gran2 [i, 1]];

x[2] = xfrm [gran2 [i, 2]]; y[2] = yfrm [gran2 [i, 2]];

myFill. Fill (g, x, y, rgb);

}

}

}

private int fx (double x)

{

return(int) (a*x+b);

}

private int fy (double y)

{

return(int) (c*y+d);

}

private void Form1_Resize (object sender, EventArgs e)

{

Ini();

Invalidate();

}

}

}

Рисунок 4.1 Реализация программы, которая строит на экране изображение выпуклого трехмерного тела при параллельной проекции

5. Центральная проекция

Задача: Написать программу, которая строит на экране изображение выпуклого трехмерного тела при центральной проекции. Удалить невидимые грани. Видимые грани закрасить оттенками серого цвета в зависимости от расположения соответствующей грани и источника света. Для закрашивания граней использовать метод сканирующей строки [2].

Решение:

Класс:

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

using System. Drawing;

using System. Collections;

namespace WindowsFormsApplication1

{

class FillTriangle

{

public void Fill (Graphics g, int[] x, int[] y, int[] rgb)

{

int maxy, miny;

ArrayList mas = new ArrayList();

float a; // Параметр альфа

miny = y[0]; maxy = miny;

for (int i = 1; i < 3; i++)

{

if (y[i] > maxy) maxy = y[i];

if (y[i] < miny) miny = y[i];

}

Pen myPen = new Pen (Color. FromArgb (255, rgb[0], rgb[1], rgb[2]));

for (int yt = miny; yt < maxy; yt++)

{

mas. Clear();

if (y[0]!= y[1])

{

a = (float) (yt-y[1]) / (float) (y[0] - y[1]);

if (a>=0&&a<=1)

mas. Insert (0, (int) (a*x[0]+(1-a)*x[1]));

}

if (y[0]!= y[2])

{

a = (float) (yt - y[2]) / (float) (y[0] - y[2]);

if (a >= 0 && a <= 1)

mas. Insert (0, (int) (a * x[0] + (1 - a) * x[2]));

}

if (y[1]!= y[2])

{

a = (float) (yt - y[2]) / (float) (y[1] - y[2]);

if (a >= 0 && a <= 1)

mas. Insert (0, (int) (a * x[1] + (1 - a) * x[2]));

}

if (mas. Count == 3)

g. DrawLine (myPen, (int) mas[1], yt, (int) mas[2], yt);

g. DrawLine (myPen, (int) mas[0], yt, (int) mas[1], yt);

}

}

}

}

Форма:

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;

namespace WindowsFormsApplication1

{

public partial class Form1: Form

{

public Form1 ()

{

InitializeComponent();

}

double[] xv = {0, 0, 30, 30, 15, 15};

double[] yv = {0, -30, -30, 0, -15, -15};

double[] zv = {0, 0, 0, 0, 30, -30};

double[] xpl = new double[6];

double[] ypl = new double[6];

int[] xfrm = new int[6];

int[] yfrm = new int[6];

int[,] gran = new int [8, 3];

double u1x, u1y, u1z, u2x, u2y, u2z, u3x, u3y, u3z;

double rx, ry, rz, ax, ay, az, sx, sy, sz;

double r1, r2, a, b, c, d, fd, rd, gx, gy, gz;

private void Form1_Load (object sender, EventArgs e)

{

ax = 15; ay = -15; az = 0;

fd = 20;

sx = 90; sy = -60; sz = 50;

gx = 100; gy = 30; gz = 20;

r1 = 35;

u3x = ax - gx; u3y = ay - gy; u3z = az - gz;

double m = Math. Sqrt (u3x * u3x + u3y * u3y + u3z * u3z);

u3x = u3x / m; u3y = u3y / m; u3z = u3z / m;

u1x = u3y; u1y = - u3x; u1z = 0;

m = Math. Sqrt (u1x * u1x + u1y * u1y + u1z * u1z);

u1x = u1x / m; u1y = u1y / m; u1z = u1z / m;

u2x = - u3y * u1z + u1y * u3z;

u2y = - u1x * u3z + u3x * u1z;

u2z = - u3x * u1y + u1x * u3y;

m = Math. Sqrt (u2x * u2x + u2y * u2y + u2z * u2z);

u2x = u2x / m; u2y = u2y / m; u2z = u2z / m;

rx = gx + u3x * fd;

ry = gy + u3y * fd;

rz = gz + u3z * fd;

rd=Math. Sqrt (Math. Pow (rx-ax, 2)+Math. Pow (ry-ay, 2)+Math. Pow (rz-az, 2));

r2= r1*fd/(rd+fd);

gran [0, 0] = 1; gran [0, 1] = 4; gran [0, 2] = 0;

gran [1, 0] = 1; gran [1, 1] = 2; gran [1, 2] = 4;

gran [2, 0] = 2; gran [2, 1] = 3; gran [2, 2] = 4;

gran [3, 0] = 3; gran [3, 1] = 0; gran [3, 2] = 4;

gran [4, 0] = 5; gran [4, 1] = 1; gran [4, 2] = 0;

gran [5, 0] = 1; gran [5, 1] = 5; gran [5, 2] = 2;

gran [6, 0] = 5; gran [6, 1] = 3; gran [6, 2] = 2;

gran [7, 0] = 5; gran [7, 1] = 0; gran [7, 2] = 3;

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

{

xpl[i] = px (xv[i], yv[i], zv[i]);

ypl[i] = py (xv[i], yv[i], zv[i]);

}

Ini();

}

private double px (double x, double y, double z)

{

double sc1 = ((x - rx) * u1x + (y - ry) * u1y + (z - rz) * u1z);

double sc2 = ((x - rx) * u3x + (y - ry) * u3y + (z - rz) * u3z);

return fd * sc1 / (sc2 + fd);

}

private double py (double x, double y, double z)

{

double sc1 = ((x - rx) * u2x + (y - ry) * u2y + (z - rz) * u2z);

double sc2 = ((x - rx) * u3x + (y - ry) * u3y + (z - rz) * u3z);

return fd * sc1 / (sc2 + fd);

}

private void Ini()

{

double wp, hp;

if (ClientSize. Width >= ClientSize. Height)

{

wp = 2 * r2 * ClientSize. Width / ClientSize. Height;

hp = 2 * r2;

}

else

{

wp = 2 * r2;

hp = 2 * r2 * ClientSize. Height / ClientSize. Width;

}

a = ClientSize. Width / wp;

b = ClientSize. Width / 2;

c = - ClientSize. Height / hp;

d = ClientSize. Height / 2;

}

private int fx (double x)

{

return (int) (a * x + b);

}

private int fy (double y)

{

return (int) (c * y + d);

}

protected override void OnPaint (PaintEventArgs e)

{

base. OnPaint(e);

Graphics g = e. Graphics;

g. Clear (Color. White);

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

{

xfrm[i] = fx (xpl[i]);

yfrm[i] = fy (ypl[i]);

}

double bx, by, bz, cx, cy, cz, nx, ny, nz;

int[] rgb = new int[3];

double cosfi;

int[] x = new int [3];

int[] y = new int [3];

FillTriangle myFill = new FillTriangle();

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

{

bx = xv [gran[i, 1]] - xv [gran[i, 0]];

by = yv [gran[i, 1]] - yv [gran[i, 0]];

bz = zv [gran[i, 1]] - zv [gran[i, 0]];

cx = xv [gran[i, 2]] - xv [gran[i, 0]];

cy = yv [gran[i, 2]] - yv [gran[i, 0]];

cz = zv [gran[i, 2]] - zv [gran[i, 0]];

nx = by * cz - bz * cy;

ny = bz * cx - bx * cz;

nz = bx * cy - by * cx;

bx = (xv [gran[i, 0]] + xv [gran[i, 1]] + xv [gran[i, 2]]) / 3;

by = (yv [gran[i, 0]] + yv [gran[i, 1]] + yv [gran[i, 2]]) / 3;

bz = (zv [gran[i, 0]] + zv [gran[i, 1]] + zv [gran[i, 2]]) / 3;

cx = bx - gx; cy = by - gy; cz = bz - gz;

if (nx * cx + ny * cy + nz * cz < 0)

{

cx = bx - sx; cy = by - sy; cz = bz - sz;

cosfi = (nx * cx + ny * cy + nz * cz) / (Math. Sqrt (nx * nx + ny * ny + nz * nz) * (Math. Sqrt (cx * cx + cy * cy + cz * cz)));

rgb[0] = (int) (-255 * cosfi / 2 + 255 / 2); //red

rgb[1] = rgb [0]; //green

rgb[2] = rgb[0]; //blue

x[0] = xfrm [gran[i, 0]]; y[0] = yfrm [gran[i, 0]];

x[1] = xfrm [gran[i, 1]]; y[1] = yfrm [gran[i, 1]];

x[2] = xfrm [gran[i, 2]]; y[2] = yfrm [gran[i, 2]];

myFill. Fill (g, x, y, rgb);

}

}

}

private void Form1_Resize (object sender, EventArgs e)

{

Ini();

Invalidate();

}

}

}

Рисунок 5.1 Реализация программы, которая строит на экране изображение выпуклого трехмерного тела при центральной проекции

Заключение

В работе были изучены некоторые разделы интерактивной графики средствами C# при помощи примеров. Данные задачи позволили хорошо рассмотреть самые главные аспекты программирования.

Благодаря своей способности быстро приспосабливаться к постоянно меняющимся потребностям в области программирования С# по-прежнему остается живым и новаторским языком. А следовательно, он представляет собой один из самых эффективных и богатых своими возможностями языков в современном программировании. Это язык, пренебречь которым не может позволить себе ни один программист. И эта книга призвана помочь вам овладеть им [3].

Список использованных источников

1 Шилдт, Г. Полное руководство С#4.0 / Г. Шилдт. - М.: Вильямс, 2011.

2 Мак-Дональд, М. WPF Windows Presentation Foundation в.NET 4.0 с примерами на C# 2010 для профессионалов / М. Мак-Дональд. - М.: Вильямс, 2011.

3 Порев, В. Компьютерная графика: учеб. Пособие / В. Порев. - БХВ-Петербург.: 2004.

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


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

  • Компьютерная графика как область информатики, занимающаяся проблемами получения различных изображений на компьютере. Области применения компьютерной графики. Двумерная графика: фрактальная, растровая и векторная. Особенности трёхмерной графики.

    реферат [756,4 K], добавлен 05.12.2010

  • Команды, используемые для построения графиков функций одной переменной (двумерная графика). Назначение и возможности команды plot (), расположенной в системной библиотеке Maple, ее операции и принцип работы. Порядок отображения графиков функций.

    лабораторная работа [141,8 K], добавлен 15.07.2009

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

    реферат [428,8 K], добавлен 09.12.2013

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

    презентация [521,5 K], добавлен 16.01.2012

  • Компьютерная графика как одно из популярных направлений использования компьютера, ее виды и особенности применения. Порядок и способы создания цифровых изображений, средства и обработка. Программы САПР и их использование в инженерной деятельности.

    реферат [19,1 K], добавлен 14.09.2009

  • Компьютерная графика как инструмент для синтеза (создания) изображений. Характеристика векторного, растрового и фрактального типов представления изображений, трёхмерная графика. Интерфейс программы "Photoshop", пример работы по коррекции фотографий.

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

  • Основные виды компьютерной графики. Достоинства и недостатки векторной графики. Сущность понятия "коэффициент прямоугольности пикселей". Математическая основа фрактальной графики. Сущность понятий "фрактал", "фрактальная геометрия", "фрактальная графика".

    контрольная работа [20,6 K], добавлен 13.07.2010

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

    реферат [29,0 K], добавлен 03.06.2010

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

    презентация [2,0 M], добавлен 04.04.2016

  • Состав, структура, назначение и описание компонентов электронного учебно-методического комплекса "Компьютерная графика". Формы реализации и требования к оформлению. Анализ рынка педагогических программных средств по обучению компьютерной графике.

    курсовая работа [572,0 K], добавлен 19.03.2015

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