19 using System.Collections.Generic;
39 public static List<Element3D>
CreateCube(Point3D center,
double size, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
41 return CreateCuboid(center, size, size, size, fill, tag, zIndex);
55 public static List<Element3D>
CreateCuboid(Point3D center,
double sizeX,
double sizeY,
double sizeZ, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
57 Point3D A =
new Point3D(center.X - sizeX * 0.5, center.Y - sizeY * 0.5, center.Z - sizeZ * 0.5);
58 Point3D B =
new Point3D(center.X + sizeX * 0.5, center.Y - sizeY * 0.5, center.Z - sizeZ * 0.5);
59 Point3D C =
new Point3D(center.X + sizeX * 0.5, center.Y + sizeY * 0.5, center.Z - sizeZ * 0.5);
60 Point3D D =
new Point3D(center.X - sizeX * 0.5, center.Y + sizeY * 0.5, center.Z - sizeZ * 0.5);
62 Point3D E =
new Point3D(center.X - sizeX * 0.5, center.Y - sizeY * 0.5, center.Z + sizeZ * 0.5);
63 Point3D F =
new Point3D(center.X + sizeX * 0.5, center.Y - sizeY * 0.5, center.Z + sizeZ * 0.5);
64 Point3D G =
new Point3D(center.X + sizeX * 0.5, center.Y + sizeY * 0.5, center.Z + sizeZ * 0.5);
65 Point3D H =
new Point3D(center.X - sizeX * 0.5, center.Y + sizeY * 0.5, center.Z + sizeZ * 0.5);
68 List<Element3D> tbr =
new List<Element3D>();
93 public static List<Element3D>
CreateRectangle(Point3D point1, Point3D point2, Point3D point3, Point3D point4, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
95 Triangle3DElement triangle1 =
new Triangle3DElement(point1, point2, point3);
96 triangle1.Fill.AddRange(fill);
98 triangle1.ZIndex = zIndex;
100 Triangle3DElement triangle2 =
new Triangle3DElement(point1, point3, point4);
101 triangle2.Fill.AddRange(fill);
103 triangle2.ZIndex = zIndex;
105 return new List<Element3D> { triangle1, triangle2 };
123 public static List<Element3D>
CreateRectangle(Point3D point1, Point3D point2, Point3D point3, Point3D point4, NormalizedVector3D point1Normal, NormalizedVector3D point2Normal, NormalizedVector3D point3Normal, NormalizedVector3D point4Normal, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
125 Triangle3DElement triangle1 =
new Triangle3DElement(point1, point2, point3, point1Normal, point2Normal, point3Normal);
126 triangle1.Fill.AddRange(fill);
128 triangle1.ZIndex = zIndex;
130 Triangle3DElement triangle2 =
new Triangle3DElement(point1, point3, point4, point1Normal, point3Normal, point4Normal);
131 triangle2.Fill.AddRange(fill);
133 triangle2.ZIndex = zIndex;
135 return new List<Element3D> { triangle1, triangle2 };
148 public static List<Element3D>
CreateSphere(Point3D center,
double radius,
int steps, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
150 List<Point3D> points =
new List<Point3D>();
152 for (
int t = 0; t <= steps; t++)
154 for (
int p = 0; p < steps * 2; p++)
156 double theta = Math.PI / steps * t;
157 double phi = Math.PI / steps * p;
159 double x = center.X + radius * Math.Sin(theta) * Math.Cos(phi);
160 double y = center.Y + radius * Math.Sin(theta) * Math.Sin(phi);
161 double z = center.Z + radius * Math.Cos(theta);
163 points.Add(
new Point3D(x, y, z));
165 if (t == 0 || t == steps)
172 List<Element3D> tbr =
new List<Element3D>(4 * steps + (points.Count - 2 - 2 * steps) * 2);
174 for (
int i = 0; i < points.Count - 1; i++)
178 for (
int j = 0; j < 2 * steps; j++)
180 Point3D p1 = points[i];
181 Point3D p3 = points[i + 1 + j];
182 Point3D p2 = points[i + 1 + (j + 1) % (2 * steps)];
184 Triangle3DElement tri =
new Triangle3DElement(p1, p2, p3, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize());
185 tri.Fill.AddRange(fill);
191 else if (i >= points.Count - 1 - 2 * steps)
193 Point3D p1 = points[i];
194 Point3D p3 = points[points.Count - 1];
195 Point3D p2 = points[points.Count - 1 - 2 * steps + (i - (points.Count - 1 - 2 * steps) + 1) % (2 * steps)];
197 Triangle3DElement tri =
new Triangle3DElement(p1, p2, p3, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize());
198 tri.Fill.AddRange(fill);
205 if ((i - 1) % (2 * steps) < 2 * steps - 1)
207 Point3D p4 = points[i + 2 * steps];
208 Point3D p3 = points[i + 2 * steps + 1];
209 Point3D p2 = points[i + 1];
210 Point3D p1 = points[i];
212 tbr.AddRange(
CreateRectangle(p1, p2, p3, p4, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize(), (center - p4).Normalize(), fill, tag, zIndex));
216 Point3D p4 = points[i + 2 * steps];
217 Point3D p3 = points[(i / (2 * steps)) * 2 * steps + 1];
218 Point3D p2 = points[(i / (2 * steps) - 1) * 2 * steps + 1];
219 Point3D p1 = points[i];
221 tbr.AddRange(
CreateRectangle(p1, p2, p3, p4, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize(), (center - p4).Normalize(), fill, tag, zIndex));
238 public static List<Element3D>
CreateTetrahedron(Point3D center,
double radius, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
240 Point3D tip =
new Point3D(center.X, center.Y - radius, center.Z);
241 Point3D base1 =
new Point3D(Math.Sqrt(8.0 / 9) * radius + center.X, center.Y + radius / 3, center.Z);
242 Point3D base2 =
new Point3D(-Math.Sqrt(2.0 / 9) * radius + center.X, center.Y + radius / 3, center.Z + Math.Sqrt(2.0 / 3) * radius);
243 Point3D base3 =
new Point3D(-Math.Sqrt(2.0 / 9) * radius + center.X, center.Y + radius / 3, center.Z - Math.Sqrt(2.0 / 3) * radius);
245 Triangle3DElement faceTriangle1 =
new Triangle3DElement(tip, base2, base1) { Tag = tag, ZIndex = zIndex };
246 faceTriangle1.Fill.AddRange(fill);
248 Triangle3DElement faceTriangle2 =
new Triangle3DElement(tip, base3, base2) { Tag = tag, ZIndex = zIndex };
249 faceTriangle2.Fill.AddRange(fill);
251 Triangle3DElement faceTriangle3 =
new Triangle3DElement(tip, base1, base3) { Tag = tag, ZIndex = zIndex };
252 faceTriangle3.Fill.AddRange(fill);
254 Triangle3DElement baseTriangle =
new Triangle3DElement(base1, base2, base3) { Tag = tag, ZIndex = zIndex };
255 baseTriangle.Fill.AddRange(fill);
257 return new List<Element3D>() { faceTriangle1, faceTriangle2, faceTriangle3, baseTriangle };
273 public static List<Element3D>
CreatePolygon(
GraphicsPath polygon2D,
double triangulationResolution, Point3D origin, NormalizedVector3D xAxis, NormalizedVector3D yAxis,
bool reverseTriangles, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
275 xAxis = (xAxis - yAxis * (xAxis * yAxis)).Normalize();
277 List<GraphicsPath> triangles = polygon2D.
Triangulate(triangulationResolution,
true).ToList();
279 List<Element3D> tbr =
new List<Element3D>(triangles.Count);
281 for (
int i = 0; i < triangles.Count; i++)
287 Point3D p13D = origin + xAxis * p1.
X + yAxis * p1.
Y;
288 Point3D p23D = origin + xAxis * p2.
X + yAxis * p2.
Y;
289 Point3D p33D = origin + xAxis * p3.
X + yAxis * p3.
Y;
291 Triangle3DElement t = !reverseTriangles ?
new Triangle3DElement(p13D, p23D, p33D) :
new Triangle3DElement(p13D, p33D, p23D);
292 t.Fill.AddRange(fill);
314 public static List<Element3D>
CreatePrism(
GraphicsPath polygonBase2D,
double triangulationResolution, Point3D bottomOrigin, Point3D topOrigin, NormalizedVector3D baseXAxis, NormalizedVector3D baseYAxis, IEnumerable<IMaterial> fill,
string tag =
null,
int zIndex = 0)
316 baseXAxis = (baseXAxis - baseYAxis * (baseXAxis * baseYAxis)).Normalize();
318 List<Element3D> tbr =
new List<Element3D>();
320 bool orientation = (baseXAxis ^ baseYAxis) * (bottomOrigin - topOrigin) > 0;
322 double[,] matrix1 = Matrix3D.RotationToAlignAWithB(
new NormalizedVector3D(0, 1, 0), baseYAxis);
323 double[,] matrix2 = Matrix3D.RotationToAlignAWithB(((Vector3D)(matrix1 *
new Point3D(1, 0, 0))).Normalize(), baseXAxis);
325 List<List<NormalizedVector3D>> normals = (from el2 in polygonBase2D.
GetLinearisationPointsNormals(triangulationResolution) select (from el in el2 select (el.X * baseXAxis + el.Y * baseYAxis).Normalize()).ToList()).ToList();
327 polygonBase2D = polygonBase2D.
Linearise(triangulationResolution);
329 tbr.AddRange(
CreatePolygon(polygonBase2D, triangulationResolution, bottomOrigin, baseXAxis, baseYAxis, orientation, fill, tag, zIndex));
330 tbr.AddRange(
CreatePolygon(polygonBase2D, triangulationResolution, topOrigin, baseXAxis, baseYAxis, !orientation, fill, tag, zIndex));
332 List<List<Point3D>> bottomPoints = (from el2 in polygonBase2D.
GetPoints() select (from el in el2 select (Point3D)(el.X * baseXAxis + el.Y * baseYAxis + (Vector3D)bottomOrigin)).ToList()).ToList();
333 List<List<Point3D>> topPoints = (from el2 in polygonBase2D.
GetPoints() select (from el in el2 select (Point3D)(el.X * baseXAxis + el.Y * baseYAxis + (Vector3D)topOrigin)).ToList()).ToList();
337 for (
int i = 0; i < bottomPoints.Count; i++)
339 for (
int j = 0; j < bottomPoints[i].Count - 1; j++)
341 tbr.AddRange(
CreateRectangle(bottomPoints[i][j], bottomPoints[i][j + 1], topPoints[i][j + 1], topPoints[i][j], normals[i][j], normals[i][j + 1], normals[i][j + 1], normals[i][j], fill, tag, zIndex));
347 for (
int i = 0; i < bottomPoints.Count; i++)
349 for (
int j = 0; j < bottomPoints[i].Count - 1; j++)
351 tbr.AddRange(
CreateRectangle(bottomPoints[i][j], topPoints[i][j], topPoints[i][j + 1], bottomPoints[i][j + 1], normals[i][j], normals[i][j], normals[i][j + 1], normals[i][j + 1], fill, tag, zIndex));
372 List<Element3D> tbr =
new List<Element3D>();
374 List<Point3D[]> addedLines =
new List<Point3D[]>();
376 void addLine(Point3D p1, Point3D p2)
378 for (
int i = 0; i < addedLines.Count; i++)
380 if ((addedLines[i][0].Equals(p1, 1e-4) && addedLines[i][1].Equals(p2, 1e-4)) || (addedLines[i][0].Equals(p2, 1e-4) && addedLines[i][1].Equals(p1, 1e-4)))
386 tbr.Add(
new Line3DElement(p1, p2) {
Colour = colour, Thickness = thickness, LineCap = lineCap,
LineDash = lineDash ??
LineDash.
SolidLine, Tag = tag, ZIndex = zIndex });
387 addedLines.Add(
new Point3D[] { p1, p2 });
390 foreach (Element3D element
in object3D)
392 if (element is Triangle3DElement triangle)
394 addLine(triangle.Point1, triangle.Point2);
395 addLine(triangle.Point2, triangle.Point3);
396 addLine(triangle.Point3, triangle.Point1);
412 public static List<Element3D>
CreatePoints(IEnumerable<Element3D> object3D,
Colour colour,
double diameter = 1,
string tag =
null,
int zIndex = 0)
414 List<Element3D> tbr =
new List<Element3D>();
416 List<Point3D> addedPoints =
new List<Point3D>();
418 void addPoint(Point3D p)
420 for (
int i = 0; i < addedPoints.Count; i++)
422 if (addedPoints[i].Equals(p, 1e-4))
428 tbr.Add(
new Point3DElement(p) {
Colour = colour, Diameter = diameter, Tag = tag, ZIndex = zIndex });
432 foreach (Element3D element
in object3D)
434 if (!(element is Point3DElement))
436 foreach (Point3D p
in element)