VectSharp  2.2.1
A light library for C# vector graphics
ObjectFactory.cs
1 /*
2  VectSharp - A light library for C# vector graphics.
3  Copyright (C) 2020-2022 Giorgio Bianchini
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, version 3.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public License
15  along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17 
18 using System;
19 using System.Collections.Generic;
20 using System.Linq;
21 using System.Text;
22 
23 namespace VectSharp.ThreeD
24 {
25  /// <summary>
26  /// A static class containing methods to create complex 3D objects.
27  /// </summary>
28  public static class ObjectFactory
29  {
30  /// <summary>
31  /// Creates a cube.
32  /// </summary>
33  /// <param name="center">The centre of the cube.</param>
34  /// <param name="size">The length of each side of the cube.</param>
35  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
36  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
37  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
38  /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the cube.</returns>
39  public static List<Element3D> CreateCube(Point3D center, double size, IEnumerable<IMaterial> fill, string tag = null, int zIndex = 0)
40  {
41  return CreateCuboid(center, size, size, size, fill, tag, zIndex);
42  }
43 
44  /// <summary>
45  /// Creates a cuboid.
46  /// </summary>
47  /// <param name="center">The centre of the cube.</param>
48  /// <param name="sizeX">The length of the sides of the cube parallel to the x axis.</param>
49  /// <param name="sizeY">The length of the sides of the cube parallel to the y axis.</param>
50  /// <param name="sizeZ">The length of the sides of the cube parallel to the z axis.</param>
51  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
52  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
53  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
54  /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the cuboid.</returns>
55  public static List<Element3D> CreateCuboid(Point3D center, double sizeX, double sizeY, double sizeZ, IEnumerable<IMaterial> fill, string tag = null, int zIndex = 0)
56  {
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);
61 
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);
66 
67 
68  List<Element3D> tbr = new List<Element3D>();
69 
70  tbr.AddRange(CreateRectangle(A, B, C, D, fill, tag, zIndex));
71  tbr.AddRange(CreateRectangle(H, G, F, E, fill, tag, zIndex));
72 
73  tbr.AddRange(CreateRectangle(E, F, B, A, fill, tag, zIndex));
74  tbr.AddRange(CreateRectangle(G, H, D, C, fill, tag, zIndex));
75 
76  tbr.AddRange(CreateRectangle(A, D, H, E, fill, tag, zIndex));
77  tbr.AddRange(CreateRectangle(F, G, C, B, fill, tag, zIndex));
78 
79  return tbr;
80  }
81 
82  /// <summary>
83  /// Creates a quadrilater. All the vertices need not be coplanar.
84  /// </summary>
85  /// <param name="point1">The first vertex of the quadrilater.</param>
86  /// <param name="point2">The second vertex of the quadrilater.</param>
87  /// <param name="point3">The third vertex of the quadrilater.</param>
88  /// <param name="point4">The fourth vertex of the quadrilater.</param>
89  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
90  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
91  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
92  /// <returns>A list containing two <see cref="Triangle3DElement"/>s representing the quadrilater.</returns>
93  public static List<Element3D> CreateRectangle(Point3D point1, Point3D point2, Point3D point3, Point3D point4, IEnumerable<IMaterial> fill, string tag = null, int zIndex = 0)
94  {
95  Triangle3DElement triangle1 = new Triangle3DElement(point1, point2, point3);
96  triangle1.Fill.AddRange(fill);
97  triangle1.Tag = tag;
98  triangle1.ZIndex = zIndex;
99 
100  Triangle3DElement triangle2 = new Triangle3DElement(point1, point3, point4);
101  triangle2.Fill.AddRange(fill);
102  triangle2.Tag = tag;
103  triangle2.ZIndex = zIndex;
104 
105  return new List<Element3D> { triangle1, triangle2 };
106  }
107 
108  /// <summary>
109  /// Creates a quadrilater, specifying the vertex normals at the four vertices. All the vertices need not be coplanar.
110  /// </summary>
111  /// <param name="point1">The first vertex of the quadrilater.</param>
112  /// <param name="point2">The second vertex of the quadrilater.</param>
113  /// <param name="point3">The third vertex of the quadrilater.</param>
114  /// <param name="point4">The fourth vertex of the quadrilater.</param>
115  /// <param name="point1Normal">The vertex normal at the first vertex of the quadrilater.</param>
116  /// <param name="point2Normal">The vertex normal at the second vertex of the quadrilater.</param>
117  /// <param name="point3Normal">The vertex normal at the third vertex of the quadrilater.</param>
118  /// <param name="point4Normal">The vertex normal at the fourth vertex of the quadrilater.</param>
119  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
120  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
121  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
122  /// <returns>A list containing two <see cref="Triangle3DElement"/>s representing the quadrilater.</returns>
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)
124  {
125  Triangle3DElement triangle1 = new Triangle3DElement(point1, point2, point3, point1Normal, point2Normal, point3Normal);
126  triangle1.Fill.AddRange(fill);
127  triangle1.Tag = tag;
128  triangle1.ZIndex = zIndex;
129 
130  Triangle3DElement triangle2 = new Triangle3DElement(point1, point3, point4, point1Normal, point3Normal, point4Normal);
131  triangle2.Fill.AddRange(fill);
132  triangle2.Tag = tag;
133  triangle2.ZIndex = zIndex;
134 
135  return new List<Element3D> { triangle1, triangle2 };
136  }
137 
138  /// <summary>
139  /// Creates a sphere.
140  /// </summary>
141  /// <param name="center">The centre of the sphere.</param>
142  /// <param name="radius">The radius of the sphere.</param>
143  /// <param name="steps">The number of meridians and parallels to use when generating the sphere.</param>
144  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
145  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
146  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
147  /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the sphere.</returns>
148  public static List<Element3D> CreateSphere(Point3D center, double radius, int steps, IEnumerable<IMaterial> fill, string tag = null, int zIndex = 0)
149  {
150  List<Point3D> points = new List<Point3D>();
151 
152  for (int t = 0; t <= steps; t++)
153  {
154  for (int p = 0; p < steps * 2; p++)
155  {
156  double theta = Math.PI / steps * t;
157  double phi = Math.PI / steps * p;
158 
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);
162 
163  points.Add(new Point3D(x, y, z));
164 
165  if (t == 0 || t == steps)
166  {
167  break;
168  }
169  }
170  }
171 
172  List<Element3D> tbr = new List<Element3D>(4 * steps + (points.Count - 2 - 2 * steps) * 2);
173 
174  for (int i = 0; i < points.Count - 1; i++)
175  {
176  if (i == 0)
177  {
178  for (int j = 0; j < 2 * steps; j++)
179  {
180  Point3D p1 = points[i];
181  Point3D p3 = points[i + 1 + j];
182  Point3D p2 = points[i + 1 + (j + 1) % (2 * steps)];
183 
184  Triangle3DElement tri = new Triangle3DElement(p1, p2, p3, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize());
185  tri.Fill.AddRange(fill);
186  tri.Tag = tag;
187  tri.ZIndex = zIndex;
188  tbr.Add(tri);
189  }
190  }
191  else if (i >= points.Count - 1 - 2 * steps)
192  {
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)];
196 
197  Triangle3DElement tri = new Triangle3DElement(p1, p2, p3, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize());
198  tri.Fill.AddRange(fill);
199  tri.Tag = tag;
200  tri.ZIndex = zIndex;
201  tbr.Add(tri);
202  }
203  else
204  {
205  if ((i - 1) % (2 * steps) < 2 * steps - 1)
206  {
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];
211 
212  tbr.AddRange(CreateRectangle(p1, p2, p3, p4, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize(), (center - p4).Normalize(), fill, tag, zIndex));
213  }
214  else
215  {
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];
220 
221  tbr.AddRange(CreateRectangle(p1, p2, p3, p4, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize(), (center - p4).Normalize(), fill, tag, zIndex));
222  }
223  }
224  }
225 
226  return tbr;
227  }
228 
229  /// <summary>
230  /// Creates a tetrahedron inscribed in a sphere.
231  /// </summary>
232  /// <param name="center">The centre of the tetrahedron.</param>
233  /// <param name="radius">The radius of the sphere in which the tetrahedron is inscribed.</param>
234  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
235  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
236  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
237  /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the sphere.</returns>
238  public static List<Element3D> CreateTetrahedron(Point3D center, double radius, IEnumerable<IMaterial> fill, string tag = null, int zIndex = 0)
239  {
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);
244 
245  Triangle3DElement faceTriangle1 = new Triangle3DElement(tip, base2, base1) { Tag = tag, ZIndex = zIndex };
246  faceTriangle1.Fill.AddRange(fill);
247 
248  Triangle3DElement faceTriangle2 = new Triangle3DElement(tip, base3, base2) { Tag = tag, ZIndex = zIndex };
249  faceTriangle2.Fill.AddRange(fill);
250 
251  Triangle3DElement faceTriangle3 = new Triangle3DElement(tip, base1, base3) { Tag = tag, ZIndex = zIndex };
252  faceTriangle3.Fill.AddRange(fill);
253 
254  Triangle3DElement baseTriangle = new Triangle3DElement(base1, base2, base3) { Tag = tag, ZIndex = zIndex };
255  baseTriangle.Fill.AddRange(fill);
256 
257  return new List<Element3D>() { faceTriangle1, faceTriangle2, faceTriangle3, baseTriangle };
258  }
259 
260  /// <summary>
261  /// Creates a flat polygon.
262  /// </summary>
263  /// <param name="polygon2D">A 2D <see cref="GraphicsPath"/> representing the polygon.</param>
264  /// <param name="triangulationResolution">The resolution that will be used to linearise curve segments in the <see cref="GraphicsPath"/>.</param>
265  /// <param name="origin">A <see cref="Point3D"/> that will correspond to the origin of the 2D reference system.</param>
266  /// <param name="xAxis">A <see cref="NormalizedVector3D"/> that will correspond to the x axis of the 2D reference system. This will be orthonormalised to the <paramref name="yAxis"/>.</param>
267  /// <param name="yAxis">A <see cref="NormalizedVector3D"/> that will correspond to the y axis of the 2D reference system.</param>
268  /// <param name="reverseTriangles">Indicates whether the order of the points (and thus the normals) of all the triangles returned by this method should be reversed.</param>
269  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
270  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
271  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
272  /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the polygon.</returns>
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)
274  {
275  xAxis = (xAxis - yAxis * (xAxis * yAxis)).Normalize();
276 
277  List<GraphicsPath> triangles = polygon2D.Triangulate(triangulationResolution, true).ToList();
278 
279  List<Element3D> tbr = new List<Element3D>(triangles.Count);
280 
281  for (int i = 0; i < triangles.Count; i++)
282  {
283  Point p1 = triangles[i].Segments[0].Point;
284  Point p2 = triangles[i].Segments[1].Point;
285  Point p3 = triangles[i].Segments[2].Point;
286 
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;
290 
291  Triangle3DElement t = !reverseTriangles ? new Triangle3DElement(p13D, p23D, p33D) : new Triangle3DElement(p13D, p33D, p23D);
292  t.Fill.AddRange(fill);
293  t.Tag = tag;
294  t.ZIndex = zIndex;
295  tbr.Add(t);
296  }
297 
298  return tbr;
299  }
300 
301  /// <summary>
302  /// Creates a prism with the specified base.
303  /// </summary>
304  /// <param name="polygonBase2D">A 2D <see cref="GraphicsPath"/> representing the base of the prism.</param>
305  /// <param name="triangulationResolution">The resolution that will be used to linearise curve segments in the <see cref="GraphicsPath"/>.</param>
306  /// <param name="bottomOrigin">A <see cref="Point3D"/> that will correspond to the origin of the 2D reference system of the bottom base.</param>
307  /// <param name="topOrigin">A <see cref="Point3D"/> that will correspond to the origin of the 2D reference system of the top base.</param>
308  /// <param name="baseXAxis">A <see cref="NormalizedVector3D"/> that will correspond to the x axis of the 2D reference system of the bases. This will be orthonormalised to the <paramref name="baseYAxis"/>.</param>
309  /// <param name="baseYAxis">A <see cref="NormalizedVector3D"/> that will correspond to the y axis of the 2D reference system of the bases.</param>
310  /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
311  /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
312  /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
313  /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the prism.</returns>
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)
315  {
316  baseXAxis = (baseXAxis - baseYAxis * (baseXAxis * baseYAxis)).Normalize();
317 
318  List<Element3D> tbr = new List<Element3D>();
319 
320  bool orientation = (baseXAxis ^ baseYAxis) * (bottomOrigin - topOrigin) > 0;
321 
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);
324 
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();
326 
327  polygonBase2D = polygonBase2D.Linearise(triangulationResolution);
328 
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));
331 
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();
334 
335  if (orientation)
336  {
337  for (int i = 0; i < bottomPoints.Count; i++)
338  {
339  for (int j = 0; j < bottomPoints[i].Count - 1; j++)
340  {
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));
342  }
343  }
344  }
345  else
346  {
347  for (int i = 0; i < bottomPoints.Count; i++)
348  {
349  for (int j = 0; j < bottomPoints[i].Count - 1; j++)
350  {
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));
352  }
353  }
354  }
355 
356  return tbr;
357  }
358 
359  /// <summary>
360  /// Creates a wireframe from a collection of <see cref="Element3D"/>s.
361  /// </summary>
362  /// <param name="object3D">The collection of <see cref="Element3D"/>s. <see cref="Line3DElement"/>s and <see cref="Point3DElement"/>s are ignored.</param>
363  /// <param name="colour">The colour of the <see cref="Line3DElement"/>s returned by this method.</param>
364  /// <param name="thickness">The thickness of the <see cref="Line3DElement"/>s returned by this method.</param>
365  /// <param name="lineCap">The line cap of the <see cref="Line3DElement"/>s returned by this method.</param>
366  /// <param name="lineDash">The line dash of the <see cref="Line3DElement"/>s returned by this method.</param>
367  /// <param name="tag">A tag that will be applied to the <see cref="Line3DElement"/>s returned by this method.</param>
368  /// <param name="zIndex">A z-index that will be applied to the <see cref="Line3DElement"/>s returned by this method.</param>
369  /// <returns>A list of <see cref="Line3DElement"/>s that constitute the wireframe.</returns>
370  public static List<Element3D> CreateWireframe(IEnumerable<Element3D> object3D, Colour colour, double thickness = 1, LineCaps lineCap = LineCaps.Butt, LineDash? lineDash = null, string tag = null, int zIndex = 0)
371  {
372  List<Element3D> tbr = new List<Element3D>();
373 
374  List<Point3D[]> addedLines = new List<Point3D[]>();
375 
376  void addLine(Point3D p1, Point3D p2)
377  {
378  for (int i = 0; i < addedLines.Count; i++)
379  {
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)))
381  {
382  return;
383  }
384  }
385 
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 });
388  }
389 
390  foreach (Element3D element in object3D)
391  {
392  if (element is Triangle3DElement triangle)
393  {
394  addLine(triangle.Point1, triangle.Point2);
395  addLine(triangle.Point2, triangle.Point3);
396  addLine(triangle.Point3, triangle.Point1);
397  }
398  }
399 
400  return tbr;
401  }
402 
403  /// <summary>
404  /// Obtains a list of <see cref="Point3DElement"/> corresponding to the vertices of a list of <see cref="Element3D"/>s.
405  /// </summary>
406  /// <param name="object3D">The collection of <see cref="Element3D"/>s. <see cref="Point3DElement"/>s are ignored.</param>
407  /// <param name="colour">The colour of the <see cref="Point3DElement"/>s returned by this method.</param>
408  /// <param name="diameter">The diameter of the <see cref="Point3DElement"/>s returned by this method.</param>
409  /// <param name="tag">A tag that will be applied to the <see cref="Point3DElement"/>s returned by this method.</param>
410  /// <param name="zIndex">A z-index that will be applied to the <see cref="Point3DElement"/>s returned by this method.</param>
411  /// <returns>A list of <see cref="Point3DElement"/>s corresponding to the vertices of the <see cref="Element3D"/>s.</returns>
412  public static List<Element3D> CreatePoints(IEnumerable<Element3D> object3D, Colour colour, double diameter = 1, string tag = null, int zIndex = 0)
413  {
414  List<Element3D> tbr = new List<Element3D>();
415 
416  List<Point3D> addedPoints = new List<Point3D>();
417 
418  void addPoint(Point3D p)
419  {
420  for (int i = 0; i < addedPoints.Count; i++)
421  {
422  if (addedPoints[i].Equals(p, 1e-4))
423  {
424  return;
425  }
426  }
427 
428  tbr.Add(new Point3DElement(p) { Colour = colour, Diameter = diameter, Tag = tag, ZIndex = zIndex });
429  addedPoints.Add(p);
430  }
431 
432  foreach (Element3D element in object3D)
433  {
434  if (!(element is Point3DElement))
435  {
436  foreach (Point3D p in element)
437  {
438  addPoint(p);
439  }
440  }
441  }
442 
443  return tbr;
444  }
445  }
446 }
VectSharp.GraphicsPath.GetLinearisationPointsNormals
IEnumerable< List< Point > > GetLinearisationPointsNormals(double resolution)
Gets a collection of the tangents at the end point of the segments in which the GraphicsPath would be...
Definition: GraphicsPath.cs:1917
VectSharp.Colour
Represents an RGB colour.
Definition: Colour.cs:26
VectSharp.GraphicsPath.Linearise
GraphicsPath Linearise(double resolution)
Linearises a GraphicsPath, replacing curve segments with series of line segments that approximate the...
Definition: GraphicsPath.cs:1844
VectSharp.ThreeD.ObjectFactory.CreateTetrahedron
static List< Element3D > CreateTetrahedron(Point3D center, double radius, IEnumerable< IMaterial > fill, string tag=null, int zIndex=0)
Creates a tetrahedron inscribed in a sphere.
Definition: ObjectFactory.cs:238
VectSharp.ThreeD.ObjectFactory.CreateWireframe
static List< Element3D > CreateWireframe(IEnumerable< Element3D > object3D, Colour colour, double thickness=1, LineCaps lineCap=LineCaps.Butt, LineDash? lineDash=null, string tag=null, int zIndex=0)
Creates a wireframe from a collection of Element3Ds.
Definition: ObjectFactory.cs:370
VectSharp.GraphicsPath
Represents a graphics path that can be filled or stroked.
Definition: GraphicsPath.cs:29
VectSharp.ThreeD.ObjectFactory.CreateSphere
static List< Element3D > CreateSphere(Point3D center, double radius, int steps, IEnumerable< IMaterial > fill, string tag=null, int zIndex=0)
Creates a sphere.
Definition: ObjectFactory.cs:148
VectSharp.ThreeD.ObjectFactory.CreatePoints
static List< Element3D > CreatePoints(IEnumerable< Element3D > object3D, Colour colour, double diameter=1, string tag=null, int zIndex=0)
Obtains a list of Point3DElement corresponding to the vertices of a list of Element3Ds.
Definition: ObjectFactory.cs:412
VectSharp.ThreeD.ObjectFactory.CreateRectangle
static List< Element3D > CreateRectangle(Point3D point1, Point3D point2, Point3D point3, Point3D point4, IEnumerable< IMaterial > fill, string tag=null, int zIndex=0)
Creates a quadrilater. All the vertices need not be coplanar.
Definition: ObjectFactory.cs:93
VectSharp.LineCaps
LineCaps
Represents line caps.
Definition: Enums.cs:71
VectSharp.ThreeD
Definition: Lights.cs:23
VectSharp.GraphicsPath.Triangulate
IEnumerable< GraphicsPath > Triangulate(double resolution, bool clockwise)
Divides a GraphicsPath into triangles.
Definition: GraphicsPath.cs:2010
VectSharp.ThreeD.ObjectFactory.CreateCuboid
static List< Element3D > CreateCuboid(Point3D center, double sizeX, double sizeY, double sizeZ, IEnumerable< IMaterial > fill, string tag=null, int zIndex=0)
Creates a cuboid.
Definition: ObjectFactory.cs:55
VectSharp.Point.Point
Point(double x, double y)
Create a new Point.
Definition: Point.cs:44
VectSharp.Point.X
double X
Horizontal (x) coordinate, measured to the right of the origin.
Definition: Point.cs:32
VectSharp.ThreeD.ObjectFactory.CreatePrism
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)
Creates a prism with the specified base.
Definition: ObjectFactory.cs:314
VectSharp.ThreeD.ObjectFactory
A static class containing methods to create complex 3D objects.
Definition: ObjectFactory.cs:29
VectSharp.LineDash
Represents instructions on how to paint a dashed line.
Definition: Enums.cs:113
VectSharp.LineDash.SolidLine
static LineDash SolidLine
A solid (not dashed) line
Definition: Enums.cs:117
VectSharp.Point
Represents a point relative to an origin in the top-left corner.
Definition: Point.cs:28
VectSharp.ThreeD.ObjectFactory.CreateRectangle
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)
Creates a quadrilater, specifying the vertex normals at the four vertices. All the vertices need not ...
Definition: ObjectFactory.cs:123
VectSharp.GraphicsPath.GetPoints
IEnumerable< List< Point > > GetPoints()
Gets a collection of the end points of all the segments in the GraphicsPath, divided by figure.
Definition: GraphicsPath.cs:1872
VectSharp.ThreeD.ObjectFactory.CreatePolygon
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)
Creates a flat polygon.
Definition: ObjectFactory.cs:273
VectSharp.Point.Y
double Y
Vertical (y) coordinate, measured to the bottom of the origin.
Definition: Point.cs:37
VectSharp.ThreeD.ObjectFactory.CreateCube
static List< Element3D > CreateCube(Point3D center, double size, IEnumerable< IMaterial > fill, string tag=null, int zIndex=0)
Creates a cube.
Definition: ObjectFactory.cs:39