using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; namespace MMCG_lab4_MESH_ { public class BSplineSurface { private double size; private const int m = 4; private Point3D start = new Point3D(300, 210, 0); private double psi; private double phi; public BSplineSurface(double size, double psi, double phi) { this.size = size; this.psi = psi; this.phi = phi; } Point3D[][] mBSplineSurface = new Point3D[][] { new Point3D[] { new Point3D(0, 0, 0), new Point3D(0, 0, 1), new Point3D(0, 1, 0), new Point3D(0, 1, 1) }, new Point3D[] { new Point3D(0.5, 0, 0), new Point3D(0.5, 0, 0.5), new Point3D(0.5, 0.5, 0), new Point3D(0.5, 0.5, 0.5) }, new Point3D[] { new Point3D(1, 0, 0), new Point3D(1, 0, 1), new Point3D(1, 1, 0), new Point3D(1, 1, 1) } }; private PointF Project(Point3D p) { Point3D e1 = new Point3D(Math.Cos(phi), Math.Sin(phi), 0); Point3D e2 = new Point3D(-1 * Math.Sin(phi) * Math.Sin(psi), Math.Cos(phi) * Math.Sin(psi), Math.Cos(psi)); double x = p.X - start.X; double y = p.Y - start.Y; double z = p.Z - start.Z; return new PointF((float)(e1.scal(new Point3D(x, y, z)) * size), (float)(e2.scal(new Point3D(x, y, z)) * size)); } public void Show(Graphics g, Pen pen) { List polygon = new List(); for (double u = 0; u <= 1.0; u += 0.01) { for (double v = 0; v <= 1.0; v += 0.01) { var pList = new List(); for (int i = 0; i < mBSplineSurface.Length; i++) { for (int j = 0; j < mBSplineSurface.Length - 2; j++) { pList.Add(new Point3D((float)(0.5f * (1f - v) * (1f - v) * mBSplineSurface[i][j].X + (0.75f - (v - 0.5f) * (v - 0.5f)) * mBSplineSurface[i][j + 1].X + 0.5f * v * v * mBSplineSurface[i][j + 2].X), (float)(0.5f * (1f - v) * (1f - v) * mBSplineSurface[i][j].Y + (0.75f - (v - 0.5f) * (v - 0.5f)) * mBSplineSurface[i][j + 1].Y + 0.5f * v * v * mBSplineSurface[i][j + 2].Y), (float)(0.5f * (1f - v) * (1f - v) * mBSplineSurface[i][j].Z + (0.75f - (v - 0.5f) * (v - 0.5f)) * mBSplineSurface[i][j + 1].Z + 0.5f * v * v * mBSplineSurface[i][j + 2].Z))); } } for (int j = 0; j < pList.Count - 2; j++) { polygon.Add(new Point3D((float)(0.5f * (1f - u) * (1f - u) * pList[j].X + (0.75f - (u - 0.5f) * (u - 0.5f)) * pList[j + 1].X + 0.5f * u * u * pList[j + 2].X), (float)(0.5f * (1f - u) * (1f - u) * pList[j].Y + (0.75f - (u - 0.5f) * (u - 0.5f)) * pList[j + 1].Y + 0.5f * u * u * pList[j + 2].Y), (float)(0.5f * (1f - u) * (1f - u) * pList[j].Z + (0.75f - (u - 0.5f) * (u - 0.5f)) * pList[j + 1].Z + 0.5f * u * u * pList[j + 2].Z))); polygon.Last().X = (float)(polygon.Last().X + start.X); polygon.Last().Y = (float)(polygon.Last().Y + start.Y); polygon.Last().Z = (float)(polygon.Last().Z + start.Z); } } var sub = polygon.Select(x => Project(x)).ToList(); for (int i = 0; i < sub.Count - 1; i++) { if (g.ClipBounds.Contains(sub[i]) && g.ClipBounds.Contains(sub[i + 1])) { g.DrawLine(pen, sub[i], sub[i + 1]); } } polygon.Clear(); } for (double v = 0; v <= 1.0; v += 0.01) { for (double u = 0; u <= 1.0; u += 0.01) { var pList = new List(); for (int i = 0; i < mBSplineSurface.Length; i++) { for (int j = 0; j < mBSplineSurface.Length - 2; j++) { pList.Add(new Point3D((float)(0.5f * (1f - v) * (1f - v) * mBSplineSurface[i][j].X + (0.75f - (v - 0.5f) * (v - 0.5f)) * mBSplineSurface[i][j + 1].X + 0.5f * v * v * mBSplineSurface[i][j + 2].X), (float)(0.5f * (1f - v) * (1f - v) * mBSplineSurface[i][j].Y + (0.75f - (v - 0.5f) * (v - 0.5f)) * mBSplineSurface[i][j + 1].Y + 0.5f * v * v * mBSplineSurface[i][j + 2].Y), (float)(0.5f * (1f - v) * (1f - v) * mBSplineSurface[i][j].Z + (0.75f - (v - 0.5f) * (v - 0.5f)) * mBSplineSurface[i][j + 1].Z + 0.5f * v * v * mBSplineSurface[i][j + 2].Z))); } } for (int j = 0; j < pList.Count - 2; j++) { polygon.Add(new Point3D((float)(0.5f * (1f - u) * (1f - u) * pList[j].X + (0.75f - (u - 0.5f) * (u - 0.5f)) * pList[j + 1].X + 0.5f * u * u * pList[j + 2].X), (float)(0.5f * (1f - u) * (1f - u) * pList[j].Y + (0.75f - (u - 0.5f) * (u - 0.5f)) * pList[j + 1].Y + 0.5f * u * u * pList[j + 2].Y), (float)(0.5f * (1f - u) * (1f - u) * pList[j].Z + (0.75f - (u - 0.5f) * (u - 0.5f)) * pList[j + 1].Z + 0.5f * u * u * pList[j + 2].Z))); polygon.Last().X = (float)(polygon.Last().X + start.X); polygon.Last().Y = (float)(polygon.Last().Y + start.Y); polygon.Last().Z = (float)(polygon.Last().Z + start.Z); } } var sub = polygon.Select(x => Project(x)).ToList(); for (int i = 0; i < sub.Count - 1; i++) { if (g.ClipBounds.Contains(sub[i]) && g.ClipBounds.Contains(sub[i + 1])) { g.DrawLine(pen, sub[i], sub[i + 1]); } } polygon.Clear(); } } } }