public static Point3D[,] CreateControlPoint4() { Point3D[,] pointArray = new Point3D[4, 4]; pointArray[0, 0] = new Point3D(-3, -1, -1); pointArray[0, 1] = new Point3D(-3, -1, 1); pointArray[0, 2] = new Point3D(-3, 1, 1); pointArray[0, 3] = new Point3D(-3, 1, -1); pointArray[1, 0] = new Point3D(-1, -1, -1); pointArray[1, 1] = new Point3D(-1, -1, 1); pointArray[1, 2] = new Point3D(-1, 1, 1); pointArray[1, 3] = new Point3D(-1, 1, -1); pointArray[2, 0] = new Point3D(1, -1, -1); pointArray[2, 1] = new Point3D(1, -1, 1); pointArray[2, 2] = new Point3D(1, 1, 1); pointArray[2, 3] = new Point3D(1, 1, -1); pointArray[3, 0] = new Point3D(3, -1, -1); pointArray[3, 1] = new Point3D(3, -1, 1); pointArray[3, 2] = new Point3D(3, 1, 1); pointArray[3, 3] = new Point3D(3, 1, -1); return pointArray; }
public Surface(Point3D[,] pointArray, int softness) : this() { this.softness = softness; if ((pointArray.GetLength(0) != 4) || (pointArray.GetLength(1) != 4)) throw new ArgumentOutOfRangeException(); for (int x = 0; x < 4; x++) for (int y = 0; y < 4; y++) { Point3DVisible point = new Point3DVisible(pointArray[x, y].X, pointArray[x, y].Y, pointArray[x, y].Z, ColorPoint); mp[x,y] = point; AddPoint(point); if (y > 0) AddEdge(new Edge(mp[x, y - 1], mp[x, y], ColorControlEdgeVertical)); if (x > 0) AddEdge(new Edge(mp[x - 1, y], mp[x, y], ColorControlEdgeHorizontal)); } CalculateSurface(); }
// using Cohen-Shutherland algorithm private bool VisibleLine(Point3D p3D1, Point3D p3D2, out int x1, out int y1, out int x2, out int y2) { Point p2D1 = Point3DToPoint(p3D1); Point p2D2 = Point3DToPoint(p3D2); x1 = (int)Math.Round(p2D1.X); y1 = (int)Math.Round(p2D1.Y); x2 = (int)Math.Round(p2D2.X); y2 = (int)Math.Round(p2D2.Y); int cohenP1 = GetCohenBitmap(new Point(x1, y1)); int cohenP2 = GetCohenBitmap(new Point(x2, y2)); if ((cohenP1 == 0) && (cohenP2 == 0)) return true; if ((cohenP1 == cohenP2) && (cohenP1 != 0)) return false; if ((cohenP1 & cohenP2) != 0) return false; double tan = (p2D2.Y - p2D1.Y) / (p2D2.X - p2D1.X); int yForX0 = (int)Math.Round((0 - p2D1.X)*tan + p2D1.Y); int xForY0 = (int)Math.Round((0 - p2D1.Y) / tan + p2D1.X); int yForXm = (int)Math.Round((bmp.PixelWidth - p2D1.X) * tan + p2D1.Y); int xForYm = (int)Math.Round((bmp.PixelHeight - p2D1.Y) / tan + p2D1.X); int intersection = 0; if ((yForX0 >= 0) && (yForX0 < bmp.PixelHeight)) intersection |= 0x01; if ((yForXm >= 0) && (yForXm < bmp.PixelHeight)) intersection |= 0x02; if ((xForY0 >= 0) && (xForY0 < bmp.PixelWidth)) intersection |= 0x04; if ((xForYm >= 0) && (xForYm < bmp.PixelWidth)) intersection |= 0x08; if ((intersection == 0) || (intersection == 0x01) || (intersection == 0x02) || (intersection == 0x04) || (intersection == 0x08)) return false; if (cohenP1 != 0) { if (((cohenP1 & 0x01) != 0) && ((intersection & 0x01) != 0)) { x1 = 0; y1 = yForX0; } else if (((cohenP1 & 0x02) != 0) && ((intersection & 0x02) != 0)) { x1 = bmp.PixelWidth - 1; y1 = yForXm; } else if (((cohenP1 & 0x04) != 0) && ((intersection & 0x04) != 0)) { x1 = xForY0; y1 = 0; } else if (((cohenP1 & 0x08) != 0) && ((intersection & 0x08) != 0)) { x1 = xForYm; y1 = bmp.PixelHeight - 1; } else return false; } if (cohenP2 != 0) { if (((cohenP2 & 0x01) != 0) && ((intersection & 0x01) != 0)) { x2 = 0; y2 = yForX0; } else if (((cohenP2 & 0x02) != 0) && ((intersection & 0x02) != 0)) { x2 = bmp.PixelWidth - 1; y2 = yForXm; } else if (((cohenP2 & 0x04) != 0) && ((intersection & 0x04) != 0)) { x2 = xForY0; y2 = 0; } else if (((cohenP2 & 0x08) != 0) && ((intersection & 0x08) != 0)) { x2 = xForYm; y2 = bmp.PixelHeight - 1; } else return false; } return true; }
private Point Point3DToPoint(Point3D p3D) { Point p2D = new Point(0, 0); switch (DrawingType) { case DrawingType.drawing3D: p2D = new Point(p3D.X - p3D.Y * scale3D * Math.Cos(alpha3D), p3D.Z - p3D.Y * scale3D * Math.Sin(alpha3D)); break; case DrawingType.drawing2Dxy: p2D = new Point(p3D.X, p3D.Y); break; case DrawingType.drawing2Dxz: p2D = new Point(p3D.X, p3D.Y); break; case DrawingType.drawing2Dyz: p2D = new Point(p3D.Y, p3D.Z); break; } p2D = new Point(scale * p2D.X * Zoom + Center.X * Zoom + bmpCenter.X, -scale * p2D.Y * Zoom + Center.Y * Zoom + bmpCenter.Y); return p2D; }
private void DrawSelected(Point3D p3D) { Point p2D = Point3DToPoint(p3D); DrawPoint(p3D, mesh.ColorPointSelected); if ((drawingAxis || drawingGrid) && (DrawingType == DrawingType.drawing3D)) { DrawLine(new Point3D(p3D.X, p3D.Y, 0), p3D, mesh.ColorPointSelectedAxis); DrawLine(new Point3D(p3D.X, p3D.Y, 0), new Point3D(0, p3D.Y, 0), mesh.ColorPointSelectedAxis); DrawLine(new Point3D(p3D.X, p3D.Y, 0), new Point3D(p3D.X, 0, 0), mesh.ColorPointSelectedAxis); } DrawCircle(p2D, 10, mesh.ColorPointSelectedAxis); DrawArrows(p3D); }
public Edge(Point3D startPoint, Point3D endPoint, Color color) : this(startPoint, endPoint) { Color = color; }
public void DeletePoint(Point3D point) { RemovePoint(point); }
public void MouseDown(Point position) { // moving with point if ((mesh != null) && (mesh.Selected != null)) { if (GetCohen(position, selectedX) == 0) isMovingSelectedX = true; else if (GetCohen(position, selectedY) == 0) isMovingSelectedY = true; else if (GetCohen(position, selectedZ) == 0) isMovingSelectedZ = true; } // moving with scene if ((!isMovingSelectedX) && (!isMovingSelectedY) && (!isMovingSelectedZ)) isMoving = true; wasMoved = false; // changing selected point if (mesh != null) { selected = null; foreach (Point3D p3D in mesh.PointList) { if (p3D is Point3DVisible) { Point p2D = Point3DToPoint(p3D); if ((position.X > (p2D.X - 10)) && (position.X < (p2D.X + 10)) && (position.Y > (p2D.Y - 10)) && (position.Y < (p2D.Y + 10))) { if (selected == null) selected = p3D; else { double d1 = Math.Sqrt(Math.Pow(selected.X - position.X, 2) + Math.Pow(selected.Y - position.Y, 2)); double d2 = Math.Sqrt(Math.Pow(p2D.X - position.X, 2) + Math.Pow(p2D.Y - position.Y, 2)); if (d2 < d1) selected = p3D; } } } } } }
private void DrawArrow(Point3D p3D1, Point3D p3D2, Color color) { DrawLine(p3D1, p3D2, color); Point3D norm = new Point3D(p3D2.X - p3D1.X, p3D2.Y - p3D1.Y, p3D2.Z - p3D1.Z); double cosA1 = norm.X / (Math.Sqrt(norm.X * norm.X + norm.Y * norm.Y)); if (double.IsNaN(cosA1)) cosA1 = 1.0; double sinA1 = norm.Y / (Math.Sqrt(norm.X * norm.X + norm.Y * norm.Y)); if (double.IsNaN(sinA1)) sinA1 = 0.0; double cosA2 = norm.X / (Math.Sqrt(norm.X * norm.X + norm.Z * norm.Z)); if (double.IsNaN(cosA2)) cosA2 = 1.0; double sinA2 = norm.Z / (Math.Sqrt(norm.X * norm.X + norm.Z * norm.Z)); if (double.IsNaN(sinA2)) sinA2 = 0.0; double moveX = (0.2 / Zoom) * norm.X / (Math.Sqrt(norm.X * norm.X + norm.Z * norm.Z)); if (double.IsNaN(moveX)) moveX = 0.0; double moveY = (0.2 / Zoom) * norm.Y / (Math.Sqrt(norm.X * norm.X + norm.Y * norm.Y)); if (double.IsNaN(moveY)) moveY = 0.0; double moveZ = (0.2 / Zoom) * norm.Z / (Math.Sqrt(norm.X * norm.X + norm.Z * norm.Z)); if (double.IsNaN(moveZ)) moveZ = 0.0; Point3D move = new Point3D(p3D2.X - moveX, p3D2.Y - moveY, p3D2.Z - moveZ); for (double radius = 0; radius < 2 * Math.PI; radius += Math.PI / 50) { double x = 0; double y = (0.05 / Zoom) * Math.Cos(radius); double z = (0.05 / Zoom) * Math.Sin(radius); // rotation axis Y double x1 = x * cosA2 - z * sinA2; double y1 = y; double z1 = x * sinA2 + z * cosA2; // rotation axis Z double x2 = x1 * cosA1 - y1 * sinA1; double y2 = x1 * sinA1 + y1 * cosA1; double z2 = z1; // moving double x3 = x2 + move.X; double y3 = y2 + move.Y; double z3 = z2 + move.Z; DrawLine(p3D2, new Point3D(x3, y3, z3), color); } }
public CoonsBspline(Point3D[,] pointArray) : this(pointArray, 8) { }
public CoonsBspline(Point3D[,] pointArray, int softness) : base(pointArray, softness) { }
public Bezier(Point3D[,] pointArray, int softness) : base(pointArray, softness) { }
public Bezier(Point3D[,] pointArray) : this(pointArray, 8) { }
public static Point3D[,] CreateControlPoint5() { Point3D[,] pointArray = new Point3D[4, 4]; pointArray[0, 0] = new Point3D(-2.5, -2.5, 3); pointArray[0, 1] = new Point3D(-2.5, 1.5, -0.5); pointArray[0, 2] = new Point3D(-2.5, 2, -0.5); pointArray[0, 3] = new Point3D(-2.5, 2.5, -0.5); pointArray[1, 0] = new Point3D(1.5, -2.5, 0.5); pointArray[1, 1] = new Point3D(-1, -1, 0); pointArray[1, 2] = new Point3D(-1, 1, 0); pointArray[1, 3] = new Point3D(-2, 2.5, -0.5); pointArray[2, 0] = new Point3D(2, -2.5, 0.5); pointArray[2, 1] = new Point3D(1, -1, 0); pointArray[2, 2] = new Point3D(1, 1, 0); pointArray[2, 3] = new Point3D(-1.5, 2.5, -0.5); pointArray[3, 0] = new Point3D(2.5, -2.5, 0.5); pointArray[3, 1] = new Point3D(2.5, -2, 0.5); pointArray[3, 2] = new Point3D(2.5, -1.5, 0.5); pointArray[3, 3] = new Point3D(2.5, 2.5, -3); return pointArray; }
private void CalculateSurface() { ClearSurface(); for (int x = 0; x < 4; x++) for (int y = 0; y < 4; y++) { mx[x, y] = mp[x, y].X; my[x, y] = mp[x, y].Y; mz[x, y] = mp[x, y].Z; } Point3D[,] pointArray = new Point3D[softness, softness]; for (int x = 0; x < softness; x++) for (int y = 0; y < softness; y++) { pointArray[x, y] = GetPoint((double)x / (double)(softness - 1), (double)y / (double)(softness - 1)); AddPoint(pointArray[x, y]); if (y > 0) AddEdge(new Edge(pointArray[x, y - 1], pointArray[x, y], ColorSurfaceEdge)); if (x > 0) AddEdge(new Edge(pointArray[x - 1, y], pointArray[x, y], ColorSurfaceEdge)); } }
private void DrawArrows(Point3D p3D) { double startOffset = 0.1 / Zoom; double endOffset = 1 / Zoom; // x-axis if (((DrawingType == DrawingType.drawing3D) || (DrawingType == DrawingType.drawing2Dxy) || (DrawingType == DrawingType.drawing2Dxz)) && (!isMovingSelectedY) && (!isMovingSelectedZ)) { Point3D p3D1 = new Point3D(p3D.X + startOffset, p3D.Y, p3D.Z); Point3D p3D2 = new Point3D(p3D.X + endOffset, p3D.Y, p3D.Z); if (!isMovingSelectedX) DrawArrow(p3D1, p3D2, mesh.ColorArrowX); else DrawArrow(p3D1, p3D2, mesh.ColorArrowSelected); Point p2D1 = Point3DToPoint(p3D1); Point p2D2 = Point3DToPoint(p3D2); selectedX = new Rect(Math.Min(p2D1.X, p2D2.X) - 10, Math.Min(p2D1.Y, p2D2.Y) - 10, Math.Abs(p2D1.X - p2D2.X) + 20, Math.Abs(p2D1.Y - p2D2.Y) + 20); } // y-axis if (((DrawingType == DrawingType.drawing3D) || (DrawingType == DrawingType.drawing2Dxy) || (DrawingType == DrawingType.drawing2Dyz)) && (!isMovingSelectedX) && (!isMovingSelectedZ)) { Point3D p3D1 = new Point3D(p3D.X, p3D.Y + startOffset, p3D.Z); Point3D p3D2 = new Point3D(p3D.X, p3D.Y + endOffset, p3D.Z); if (!isMovingSelectedY) DrawArrow(p3D1, p3D2, mesh.ColorArrowY); else DrawArrow(p3D1, p3D2, mesh.ColorArrowSelected); Point p2D1 = Point3DToPoint(p3D1); Point p2D2 = Point3DToPoint(p3D2); selectedY = new Rect(Math.Min(p2D1.X, p2D2.X) - 10, Math.Min(p2D1.Y, p2D2.Y) - 10, Math.Abs(p2D1.X - p2D2.X) + 20, Math.Abs(p2D1.Y - p2D2.Y) + 20); } // z-axis if (((DrawingType == DrawingType.drawing3D) || (DrawingType == DrawingType.drawing2Dxz) || (DrawingType == DrawingType.drawing2Dyz)) && (!isMovingSelectedX) && (!isMovingSelectedY)) { Point3D p3D1 = new Point3D(p3D.X, p3D.Y, p3D.Z + startOffset); Point3D p3D2 = new Point3D(p3D.X, p3D.Y, p3D.Z + endOffset); if (!isMovingSelectedZ) DrawArrow(p3D1, p3D2, mesh.ColorArrowZ); else DrawArrow(p3D1, p3D2, mesh.ColorArrowSelected); Point p2D1 = Point3DToPoint(p3D1); Point p2D2 = Point3DToPoint(p3D2); selectedZ = new Rect(Math.Min(p2D1.X, p2D2.X) - 10, Math.Min(p2D1.Y, p2D2.Y) - 10, Math.Abs(p2D1.X - p2D2.X) + 20, Math.Abs(p2D1.Y - p2D2.Y) + 20); } }
public Edge(Point3D startPoint, Point3D endPoint) { StartPoint = startPoint; EndPoint = endPoint; }
private void DrawLine(Point3D p3D1, Point3D p3D2, Color color) { int x1, y1, x2, y2; if (VisibleLine(p3D1, p3D2, out x1, out y1, out x2, out y2)) bmp.DrawLine(x1, y1, x2, y2, color); }
public void AddPoint(Point3D point) { if (!pointList.Contains(point)) pointList.Add(point); }
private void DrawPoint(Point3D p3D, Color color) { Point p2D = Point3DToPoint(p3D); int x1 = (int)Math.Round(p2D.X) - 1; int y1 = (int)Math.Round(p2D.Y) - 1; int x2 = (int)Math.Round(p2D.X); int y2 = (int)Math.Round(p2D.Y); int cohenP1 = GetCohenBitmap(new Point(x1, y1)); int cohenP2 = GetCohenBitmap(new Point(x2, y2)); if ((cohenP1 == 0) && (cohenP2 == 0)) bmp.DrawRectangle(x1, y1, x2, y2, color); }
private void RemovePoint(Point3D point) { if (pointList.Remove(point)) { List<Edge> deleteEdgeList = new List<Edge>(); foreach (Edge edge in edgeList) { if (edge.StartPoint.Equals(point) || edge.EndPoint.Equals(point)) { deleteEdgeList.Add(edge); } } foreach (Edge edge in deleteEdgeList) RemoveEdge(edge); } }
public static Point3D[,] CreateControlPoint6() { Point3D[,] pointArray = new Point3D[4, 4]; pointArray[0, 0] = new Point3D(-1.5, -1.5, -1); pointArray[0, 1] = new Point3D(-2, -0.5, -1); pointArray[0, 2] = new Point3D(-2, 0.5, -1); pointArray[0, 3] = new Point3D(-1.5, 1.5, -1); pointArray[1, 0] = new Point3D(-0.5, -2, -1); pointArray[1, 1] = new Point3D(-4, -4, 1); pointArray[1, 2] = new Point3D(-4, 4, 1); pointArray[1, 3] = new Point3D(-0.5, 2, -1); pointArray[2, 0] = new Point3D(0.5, -2, -1); pointArray[2, 1] = new Point3D(4, -4, 1); pointArray[2, 2] = new Point3D(4, 4, 1); pointArray[2, 3] = new Point3D(0.5, 2, -1); pointArray[3, 0] = new Point3D(1.5, -1.5, -1); pointArray[3, 1] = new Point3D(2, -0.5, -1); pointArray[3, 2] = new Point3D(2, 0.5, -1); pointArray[3, 3] = new Point3D(1.5, 1.5, -1); return pointArray; }