Тестирование.
Моделирование геометрических объектов
If (x1 > x2) { int xt = x1; x1 = x2; x2 = xt; Vector3D NT = NQ; NQ = NR; NR = NT; }. If (x1 > x2) { int xt = x1; x1 = x2; x2 = xt; double It = Iq; Iq = Ir; Ir = It; }. Public Polygon (Color acol, Vertex Vertexes, int Start, int Count, bool Order). Mv. ScreenTrans (d, Ro, pictureBox1. Width / 2, pictureBox1. Height / 2); Double u = ((double)(y — ABCD. s. Y)) / (ABCD. s. Y — ABCD. s. Y); Float u… Читать ещё >
Тестирование. Моделирование геометрических объектов (реферат, курсовая, диплом, контрольная)
В ходе работы была построена трехмерная модель конуса, реализована закраска методом Гуро, фигуру можно посмотреть в любом ракурсу.
Рисунок 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 V = new List ();
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 PS = new List ();
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 LP = new List ();
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;
}.
}.
}.