Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Windows.Forms;
- namespace Graphics2nd
- {
- public partial class ThreeDimencions : Form
- {
- delegate double Func(double aa, double bb);
- struct Point3d
- {
- public double x, y, z;
- public Point3d(double a, double b, double c)
- {
- x = a; y = b; z = c;
- }
- }
- struct _Graph
- {
- public double phi, psi;
- public double a, b, c, d;
- public double Max, Min;
- public Func[] current;
- }
- struct Point
- {
- public double X;
- public double Y;
- public Point(double x, double y)
- {
- this.X = x;
- this.Y = y;
- }
- }
- _Graph graph;
- Point3d E1, E2, E3;
- Point From, Delta;
- Bitmap bitmap;
- double fAngle, sAngle;
- bool isButtonPressed = false;
- double mass;
- List<List<Point>> toDraw;
- List<List<Point3d>> Calculated;
- int Closeness = 9;
- double[,] ZBUF;
- int[,] ZCOLOR;
- public ThreeDimencions()
- {
- InitializeComponent();
- Delta = new Point(Width/2, Height/2);
- toDraw = new List<List<Point>>();
- Calculated = new List<List<Point3d>>();
- graph = new _Graph();
- graph.a = -1;
- graph.b = 1;
- graph.current = new Func[3];
- graph.c = -1;
- graph.d = 1;
- fAngle = 0;
- sAngle = 0;
- graph.phi = fAngle * Math.PI / 180;
- graph.psi = sAngle * Math.PI / 180;
- E1 = new Point3d(Math.Cos(graph.phi), Math.Sin(graph.phi), 0);
- E2 = new Point3d(-Math.Sin(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.phi) *Math.Sin(graph.psi) , Math.Cos(graph.psi));
- E3 = vectVect(E1, E2);
- mass = 0.5;
- ZBUF = new double[Width, Height];
- ZCOLOR = new int[Width, Height];
- bitmap = new Bitmap(Width, Height);
- Paint += (object a, PaintEventArgs e) => { e.Graphics.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height); };
- MouseWheel += (object a, MouseEventArgs e) =>
- {
- if (e.Delta > 0) mass *= 1.1; else mass *= 0.9;
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- FindProjection();
- DrawAxis();
- Draw();
- };
- //Log();
- //FillAndDraw();
- initzbuf();
- fill_tr(new Point3d(0.5, 0.5, 0.5), new Point3d(0.3, 0.3, 0.3), new Point3d(0.9, 0.2, 0.8), 130);
- Display();
- DoubleBuffered = true;
- }
- private void initzbuf()
- {
- for (int i = 0; i < Width; i++)
- for (int j = 0; j < Height; j++)
- ZBUF[i, j] = float.MaxValue;
- }
- private void Display()
- {
- for (int i = 0; i < Width; i++)
- for (int j = 0; j < Height; j++)
- bitmap.SetPixel(i, j , Color.FromArgb(ZCOLOR[i, j]));
- }
- private void Put_In_Zbuf(int x, int y, double z, int c)
- {
- if (z < ZBUF[x, y])
- {
- ZBUF[x, y] = z;
- ZCOLOR[x, y] = c;
- }
- }
- private void fill_tr(Point3d A, Point3d B, Point3d C, int color)
- {
- double SX, SY;
- SX = mass * Width;
- SY = mass * Height;
- double u, v, du, dv;
- Point3d R = new Point3d();
- int X, Y;
- du = 0.007;
- dv = 0.007;
- for (u = 0; u <= 1.0; u += du)
- for (v = 0; v <= 1 - u; v += dv)
- {
- R.x = A.x + u * (B.x - A.x) + v * (C.x - A.x);
- R.y = A.y + u * (B.y - A.y) + v * (C.y - A.y);
- R.z = A.z + u * (B.z - A.z) + v * (C.z - A.z);
- X = (int)((SX * vectScalar(R, E1)) + Delta.X);
- Y = (int)((SX * vectScalar(R, E2)) + Delta.Y);
- Put_In_Zbuf(X, Y, R.z, color);
- }
- }
- private void Test()
- {
- graph.a = -Math.PI;
- graph.b = Math.PI;
- graph.c = -Math.PI;
- graph.d = Math.PI;
- graph.current[0] = new Func((u, v) => { return Math.Cos(u); });
- graph.current[1] = new Func((u, v) => { return v; });
- graph.current[2] = new Func((u, v) => { return u; });
- }
- private void Paraboloid()
- {
- graph.a = -Math.PI;
- graph.b = Math.PI;
- graph.c = -2;
- graph.d = 2 ;
- graph.current[0] = new Func((u, v) => { return Math.Cosh(u) * v; });
- graph.current[1] = new Func((u, v) => { return Math.Sinh(u) *v; });
- graph.current[2] = new Func((u, v) => { return v*v; });
- }
- private void Mebius()
- {
- graph.a = 0;
- graph.b = 2 * Math.PI;
- graph.c = -1;
- graph.d = 1;
- graph.current[0] = new Func((u, v) => { return (1+v/2*Math.Cos(u/2))*Math.Cos(u); });
- graph.current[1] = new Func((u, v) => { return (1 + v / 2 * Math.Cos(u / 2)) * Math.Sin(u); });
- graph.current[2] = new Func((u, v) => { return v / 2 * Math.Sin(u / 2); });
- }
- private void Thor()
- {
- graph.a = -Math.PI-1;
- graph.b = Math.PI+1;
- graph.c = -Math.PI-1;
- graph.d = Math.PI+1;
- graph.current[0] = new Func((u, v) => { return Math.Cos(u) * (3 + Math.Cos(v)); });
- graph.current[1] = new Func((u, v) => { return Math.Sin(u) * (3 + Math.Cos(v)); });
- graph.current[2] = new Func((u, v) => { return Math.Sin(v); });
- }
- private void Dini()
- {
- graph.a = 0;
- graph.b = 4 * Math.PI;
- graph.c = 0.001;
- graph.d = 2;
- graph.current[0] = new Func((u, v) => { return Math.Cos(u) * Math.Sin(v); });
- graph.current[1] = new Func((u, v) => { return Math.Sin(u) * Math.Cos(v); });
- graph.current[2] = new Func((u, v) => { return Math.Cos(v) + Math.Log(Math.Tan(v / 2)) + 0.2 * u - 4; });
- }
- private void Cube()
- {
- graph.a = 0;
- graph.b = 2*Math.PI;
- graph.c = 0;
- graph.d = Math.PI;
- graph.current[0] = new Func((u, v) => { return 2 * Math.Cos(u) * Math.Cos(v); });
- graph.current[1] = new Func((u, v) => { return 2 * Math.Cos(u) * Math.Sin(v); });
- graph.current[2] = new Func((u, v) => { return 2*Math.Sin(u); });
- }
- private void Log()
- {
- graph.a = 0;
- graph.b = 3 * Math.PI;
- graph.c = -Math.PI;
- graph.d = Math.PI;
- graph.current[0] = new Func((u, v) => { return u * Math.Cos(u) * (Math.Cos(v) + 1); });
- graph.current[1] = new Func((u, v) => { return u * Math.Sin(u) * (Math.Cos(v) + 1); });
- graph.current[2] = new Func((u, v) => { return u * Math.Sin(v); });
- }
- private void ThreeDimencions_MouseDown(object sender, MouseEventArgs e)
- {
- From = new Point(PointToClient(MousePosition).X, PointToClient(MousePosition).Y);
- if (e.Button == MouseButtons.Left)
- {
- isButtonPressed = true;
- }
- }
- private void ThreeDimencions_MouseUp(object sender, MouseEventArgs e)
- {
- isButtonPressed = false;
- if(e.Button == MouseButtons.Right)
- {
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- Delta.X += PointToClient(MousePosition).X - From.X;
- Delta.Y += PointToClient(MousePosition).Y - From.Y;
- FindProjection();
- DrawAxis();
- Draw();
- }
- }
- private void ThreeDimencions_MouseMove(object sender, MouseEventArgs e)
- {
- if (isButtonPressed)
- {
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- double OnX = (PointToClient(MousePosition).X - From.X) * 0.0001;
- double OnY = (PointToClient(MousePosition).Y - From.Y) * 0.0001;
- for (int i = 0; i < Calculated.Count; i++)
- {
- for (int j = 0; j < Calculated[i].Count; j++)
- {
- Calculated[i][j] = new Point3d(Calculated[i][j].x, Calculated[i][j].y * Math.Cos(OnY) + Calculated[i][j].z * Math.Sin(OnY),
- -Calculated[i][j].y * Math.Sin(OnY) + Calculated[i][j].z * Math.Cos(OnY));
- Calculated[i][j] = new Point3d(Calculated[i][j].x * Math.Cos(OnX) + Calculated[i][j].z * Math.Sin(OnX), Calculated[i][j].y,
- -Calculated[i][j].x * Math.Sin(OnX) + Calculated[i][j].z * Math.Cos(OnX));
- }
- }
- FindProjection();
- DrawAxis();
- Draw();
- }
- }
- void FillAndDraw()
- {
- double x, y, dx, dy;
- dx = (graph.b - graph.a) / 20;
- dy = (graph.d - graph.c) / 20;
- List<Point3d> toAdd;
- for (x = graph.a; x <= graph.b; x += dx)
- {
- toAdd = new List<Point3d>();
- y = graph.c;
- toAdd.Add(new Point3d(graph.current[0](x, y), graph.current[1](x, y), graph.current[2](x, y)));
- for (y = graph.c; y <= graph.d; y += dy)
- {
- toAdd.Add(new Point3d(graph.current[0](x, y), graph.current[1](x, y), graph.current[2](x, y)));
- }
- Calculated.Add(new List<Point3d>(toAdd));
- }
- for (y = graph.c; y <= graph.d; y += dy)
- {
- toAdd = new List<Point3d>();
- x = graph.a;
- toAdd.Add(new Point3d(graph.current[0](x, y), graph.current[1](x, y), graph.current[2](x, y)));
- for (x = graph.a; x <= graph.b; x += dx)
- {
- toAdd.Add(new Point3d(graph.current[0](x, y), graph.current[1](x, y), graph.current[2](x, y)));
- }
- Calculated.Add(new List<Point3d>(toAdd));
- }
- FindProjection();
- DrawAxis();
- Draw();
- }
- void FindProjection()
- {
- double SX, SY;
- List<Point> toAdd;
- SX = mass * Width;
- SY = mass * Height;
- foreach(List<Point3d> list in Calculated)
- {
- toAdd = new List<Point>();
- foreach(Point3d p in list)
- {
- toAdd.Add(new Point((int)(SX * vectScalar(p, E1)) + Delta.X, (int)(SY * vectScalar(p, E2)) + Delta.Y));
- }
- toDraw.Add(toAdd);
- }
- }
- void DrawAxis()
- {
- double SX, SY;
- SX = 500;
- SY = 500;
- Line((int)(SX * vectScalar(E1, new Point3d(1,0,0)) + Delta.X) ,(int)Delta.X,
- (int)(SY * vectScalar(E1, new Point3d(0,0,1)) + Delta.Y), (int)Delta.Y, bitmap, Color.Red);
- Line((int)(SX * vectScalar(E2, new Point3d(1, 0, 0)) + Delta.X), (int)Delta.X,
- (int)(SY * vectScalar(E2, new Point3d(0, 0, 1)) + Delta.Y), (int)Delta.Y, bitmap, Color.Green);
- Line((int)(SX * vectScalar(E3, new Point3d(1, 0, 0)) + Delta.X), (int)Delta.X,
- (int)(SY * vectScalar(E3, new Point3d(0, 0, 1)) + Delta.Y), (int)Delta.Y, bitmap, Color.Blue);
- }
- void Draw()
- {
- for (int i = 0; i < toDraw.Count; i++)
- {
- for (int j = 0; j < toDraw[i].Count-1; j++)
- {
- Line((int)toDraw[i][j].X, (int)toDraw[i][j+1].X, (int)toDraw[i][j].Y, (int)toDraw[i][j+1].Y, bitmap, Color.Black);
- }
- }
- toDraw = new List<List<Point>>();
- }
- private void ThreeDimencions_KeyDown(object sender, KeyEventArgs e)
- {
- if(e.KeyCode == Keys.Down)
- {
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- graph.psi += 22.5 * Math.PI / 180;
- E1 = new Point3d(Math.Cos(graph.phi), Math.Sin(graph.phi), 0);
- E2 = new Point3d(-Math.Sin(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.psi));
- E3 = vectVect(E1, E2);
- FindProjection();
- DrawAxis();
- Draw();
- }
- if(e.KeyCode == Keys.Up)
- {
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- graph.psi -= 22.5*Math.PI/180;
- E1 = new Point3d(Math.Cos(graph.phi), Math.Sin(graph.phi), 0);
- E2 = new Point3d(-Math.Sin(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.psi));
- E3 = vectVect(E1, E2);
- FindProjection();
- DrawAxis();
- Draw();
- }
- if(e.KeyCode == Keys.Left)
- {
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- graph.phi += 22.5 * Math.PI / 180;
- E1 = new Point3d(Math.Cos(graph.phi), Math.Sin(graph.phi), 0);
- E2 = new Point3d(-Math.Sin(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.psi));
- E3 = vectVect(E1,E2);
- FindProjection();
- DrawAxis();
- Draw();
- }
- if(e.KeyCode == Keys.Right)
- {
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- graph.phi -= 22.5 * Math.PI / 180;
- E1 = new Point3d(Math.Cos(graph.phi), Math.Sin(graph.phi), 0);
- E2 = new Point3d(-Math.Sin(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.phi) * Math.Sin(graph.psi), Math.Cos(graph.psi));
- E3 = vectVect(E1, E2);
- FindProjection();
- DrawAxis();
- Draw();
- }
- if(e.KeyCode == Keys.Space)
- {
- List<Point3d> toAdd = new List<Point3d>();
- Calculated = new List<List<Point3d>>();
- toAdd.Add(new Point3d(0, 0, 0));
- toAdd.Add(new Point3d(0, 1, 0));
- toAdd.Add(new Point3d(1, 1, 0));
- toAdd.Add(new Point3d(1, 0, 0));
- toAdd.Add(new Point3d(0, 0, 0));
- Calculated.Add(toAdd);
- toAdd = new List<Point3d>();
- toAdd.Add(new Point3d(0, 0, 1));
- toAdd.Add(new Point3d(0, 1, 1));
- toAdd.Add(new Point3d(1, 1, 1));
- toAdd.Add(new Point3d(1, 0, 1));
- toAdd.Add(new Point3d(0, 0, 1));
- Calculated.Add(toAdd);
- toAdd = new List<Point3d>();
- toAdd.Add(new Point3d(0, 0, 0));
- toAdd.Add(new Point3d(0, 0, 1));
- Calculated.Add(toAdd);
- toAdd = new List<Point3d>();
- toAdd.Add(new Point3d(0, 1, 0));
- toAdd.Add(new Point3d(0, 1, 1));
- Calculated.Add(toAdd);
- toAdd = new List<Point3d>();
- toAdd.Add(new Point3d(1, 0, 0));
- toAdd.Add(new Point3d(1, 0, 1));
- Calculated.Add(toAdd);
- toAdd = new List<Point3d>();
- toAdd.Add(new Point3d(1, 1, 0));
- toAdd.Add(new Point3d(1, 1, 1));
- Calculated.Add(toAdd);
- toAdd = new List<Point3d>();
- Text += "1";
- FindProjection();
- DrawAxis();
- Draw();
- }
- }
- private void bezieToolStripMenuItem_Click(object sender, EventArgs e)
- {
- FindProjection();
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- Text = toDraw.Count.ToString();
- foreach (List<Point> Points in toDraw)
- {
- List<Point> List = new List<Point>();
- List.Add(Points[0]);
- for (int i = 1; i < Points.Count - 1; i++)
- {
- for (int j = 0; j < Closeness; j++)
- {
- List.Add(Points[i]);
- }
- }
- List.Add(Points[Points.Count - 1]);
- Text += "2";
- DeKastell(List, Closeness, bitmap, Color.Black);
- }
- toDraw.Clear();
- }
- private void DeKastell(List<Point> LIST, int Closeness, Bitmap bmp, Color color)//ШАГ МЕНЯТЬ
- {
- Point New, Old;
- int n;
- List<Point> R = new List<Point>(LIST.Count);
- List<Point> Q = new List<Point>(LIST.Count);
- for (int j = 0; j < LIST.Count; j++)
- {
- Q.Add(new Point(0, 0));
- }
- Old = new Point(LIST[0].X, LIST[0].Y);
- for (double t = 0; t < 1; t += 0.001)
- {
- n = LIST.Count;
- foreach (Point a in LIST)
- {
- R.Add(new Point(a.X, a.Y));
- }
- while (n > 0)
- {
- for (int j = 0; j < n - 1; j++)
- {
- Q[j] = new Point(R[j].X + t * (R[j + 1].X - R[j].X),
- R[j].Y + t * (R[j + 1].Y - R[j].Y));
- }
- n--;
- for (int j = 0; j < n; j++)
- {
- R[j] = new Point(Q[j].X, Q[j].Y);
- }
- }
- New = new Point(R[0].X, R[0].Y);
- Line((int)Old.X, (int)New.X, (int)Old.Y, (int)New.Y, bmp, color);
- Old = new Point(New.X, New.Y);
- R = new List<Point>();
- for (int j = 0; j < LIST.Count; j++)
- {
- Q[j] = new Point(0, 0);
- }
- }
- Line((int)Old.X, (int)LIST[LIST.Count-1].X, (int)Old.Y, (int)LIST[LIST.Count-1].Y, bmp, color);
- }
- private void splineToolStripMenuItem_Click(object sender, EventArgs e)
- {
- FindProjection();
- bitmap = new Bitmap(bitmap.Width, bitmap.Height);
- foreach (List<Point> points in toDraw)
- {
- if (points.Count > 2)
- {
- points.Add(points[0]);
- points.Add(points[1]);
- }
- Quadratic(points,bitmap, Color.Black);
- }
- toDraw.Clear();
- }
- private void Quadratic(List<Point> Points, Bitmap bitmap, Color color)//ШАГ МЕНЯТЬ
- {
- Point Old;
- Point New;
- int i = 0;
- Old = new Point((Points[i].X + Points[i + 1].X) / 2, (Points[i].Y + Points[i + 1].Y) / 2);
- for (i = 0; i < Points.Count - 2; i++)
- {
- for (double j = 0; j < 1.0; j += 0.01)
- {
- New = new Point((0.5 * (1 - j) * (1 - j) * Points[i].X
- + (0.75 - (j - 0.5) * (j - 0.5)) * Points[i + 1].X
- + 0.5 * j * j * Points[i + 2].X),
- (0.5 * (1 - j) * (1 - j) * Points[i].Y
- + (0.75 - (j - 0.5) * (j - 0.5)) * Points[i + 1].Y + 0.5 * j * j * Points[i + 2].Y));
- Line((int)Old.X, (int)New.X, (int)Old.Y, (int)New.Y, bitmap, Color.Black);
- Old = new Point(New.X, New.Y);
- }
- }
- }
- private void ThreeDimencions_FormClosed(object sender, FormClosedEventArgs e)
- {
- Form1.IsWindowOpened = false;
- }
- Point3d vectVect(Point3d a, Point3d b)
- {
- return new Point3d(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
- }
- double vectScalar(Point3d a, Point3d b)
- {
- return a.x * b.x + a.y * b.y + a.z * b.z;
- }
- private void Line(int FirstPointX, int SecondPointX, int FirstPointY, int SecondPointY, Bitmap map, Color color)
- {
- if (!(FirstPointX == SecondPointX && SecondPointY == FirstPointY))
- {
- int A = SecondPointY - FirstPointY;
- int B = FirstPointX - SecondPointX;
- int sgn = Math.Abs(A) > Math.Abs(B) ? 1 : -1;
- int sgnA = A < 0 ? -1 : 1;
- int sgnB = B < 0 ? -1 : 1;
- int f = 0;
- if (FirstPointX > 0 && FirstPointX < map.Width && FirstPointY > 0 && FirstPointY < map.Height)
- map.SetPixel(FirstPointX, FirstPointY, color);
- int x = FirstPointX, y = FirstPointY;
- if (sgn == -1)
- {
- do
- {
- f += 2 * A * sgnA;
- if (f > 1)
- {
- f -= 2 * B * sgnB;
- y += sgnA;
- }
- x -= sgnB;
- if (x > 0 && x < map.Width && y > 0 && y < map.Height)
- map.SetPixel(x, y, color);
- } while (x != SecondPointX || y != SecondPointY);
- }
- else
- {
- do
- {
- f += 2 * B * sgnB;
- if (f > 1)
- {
- f -= 2 * A * sgnA;
- x -= sgnB;
- }
- y += sgnA;
- if (x > 0 && x < map.Width && y > 0 && y < map.Height)
- map.SetPixel(x, y, color);
- } while (x != SecondPointX || y != SecondPointY);
- }
- Invalidate();
- }
- } // линия
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement