SUAPI-CppWrapper
C++WrapperforSketchUpCAPI
Geometry.hpp
1 //
2 // Geometry.hpp
3 //
4 // Sketchup C++ Wrapper for C API
5 // MIT License
6 //
7 // Copyright (c) 2017 Tom Kaneko
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 
16 // The above copyright notice and this permission notice shall be included in all
17 // copies or substantial portions of the Software.
18 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 // SOFTWARE.
26 //
27 
28 // Remove Visual Studio min and max macros
29 #ifdef WIN32
30  #undef min
31  #undef max
32 #endif
33 
34 #ifndef Geometry_h
35 #define Geometry_h
36 
37 #include <algorithm>
38 #include <vector>
39 
40 #include <SketchUpAPI/geometry.h>
41 #include <SketchUpAPI/model/edge.h>
42 #include <SketchUpAPI/model/face.h>
43 
44 namespace CW {
45 
46 // Forward declarations
47 class Face;
48 class Edge;
49 
50 /**
51 * Radians class deals with calculating radians.
52 * Usage: Radians(double) - converts double into radians. Negative and values more than 2*pi will be made into a value between 0 and 2*pi.
53 */
54 class Radians
55 {
56 private:
57 
58 public:
59  double m_val;
60  static constexpr double PI = 3.141592653589793;
61  static constexpr double PI2 = PI * 2;
62  // Estimate the degree of correctness of angles (Sketchup Tolerance is 1/1000", so try to make some sort of guess - suggest discrepancies of 1/1000" over radians rotations over 30m (approx 1000")
63  constexpr static double EPSILON = 0.0000000000005; // Sketchup Tolerance is 1/1000"
64 
65  Radians() {};
66  Radians(const double &rhs);
67 
68  /**
69  * Copy constructor
70  */
71  Radians(const Radians &radians);
72 
73  /**
74  * Radians can be cast simply into a double without data loss.
75  */
76  operator double() const;
77 
78  /**
79  * Overloaded assignment operator
80  */
81  Radians &operator=(const Radians &radians);
82 
83  /**
84  * Arithmetic operator overloads. These work like doubles, but will always give a value between 0 and 2*pi
85  */
86  Radians operator+(const double value) const;
87  Radians operator-(const double value) const;
88  Radians operator*(const double multiplier) const;
89  Radians operator/(const double divider) const;
90 
91  bool operator==(const Radians& rhs) const;
92  bool operator==(const double rhs) const;
93 
94  /**
95  * Gives the difference between the two radians values as a positive double value.
96  */
97  double difference(const Radians& other) const;
98 
99  // TODO: below does not look right
100  bool closest(const Radians& value);
101 };
102 
103 class Point3D;
104 
105 /*
106 * Vector3D class is analagous to SUVector3D struct, and holds the same member variables.
107 *
108 * Class methods are included to allow easy vector mathematics.
109 * Initialisation:
110 * - Vector3D(SUVector3D vec)
111 * - Vector3D(double x, double y, double z)
112 */
113 class Vector3D {
114 
115  protected:
116  SUVector3D m_vector;
117  bool is_null = false; // Invalid flag
118 
119  public:
120  double &x;
121  double &y;
122  double &z;
123  constexpr static double EPSILON = 0.0005; // Sketchup Tolerance is 1/1000"
124 
125  Vector3D();
126  /**
127  * SUVector3D objects are easily converted to Vector3D without data loss
128  */
129  Vector3D( SUVector3D su_vector);
130  Vector3D( double x, double y, double z);
131 
132  /**
133  * Invaid, or NULL Vector3D objects can be simulated with this constructor.
134  */
135  Vector3D(bool valid);
136 
137  /**
138  * Returns the vector between start and end points of an edge.
139  */
140  Vector3D( const Edge &edge);
141 
142  /**
143  * Allow conversion from Point3D.
144  */
145  explicit Vector3D( const Point3D& point);
146 
147  /*
148  * Cast to SUVector3D object
149  */
150  operator SUVector3D() const;
151 
152  /**
153  * Pointer to internal SUVector3D object
154  */
155  operator const SUVector3D*() const;
156 
157  /*
158  * Cast to Point3D object
159  */
160  operator Point3D() const;
161 
162  /*
163  * Copy constructor
164  */
165  Vector3D(const Vector3D &vector);
166 
167  /**
168  * Copy assignment operator
169  */
170  Vector3D &operator=(const Vector3D &vector);
171  Vector3D &operator=(const SUVector3D &vector);
172 
173  /**
174  * Arithmetic operator overloads
175  */
176  Vector3D operator+(const Vector3D &vector) const;
177  Vector3D operator+(const SUVector3D &vector) const {return *this + Vector3D(vector);}
178  friend Point3D operator+(const Vector3D &lhs, const Point3D& rhs);
179 
180  Vector3D operator-() const;
181  Vector3D operator-(const Vector3D &vector) const;
182  Vector3D operator-(const SUVector3D &vector) const {return *this - Vector3D(vector);}
183  Vector3D operator*(const double &scalar) const;
184  Vector3D operator/(const double &scalar) const;
185 
186  /**
187  * Allows the multiplication operator to be on the other side of the vector.
188  */
189  friend Vector3D operator*(const double &lhs, const Vector3D &rhs);
190 
191  /**
192  * Comparator operator overloads
193  */
194  friend bool operator==(const Vector3D& lhs, const Vector3D& rhs);
195 
196  friend bool operator!=(const Vector3D& lhs, const Vector3D& rhs);
197 
198  /**
199  * Validty check
200  */
201  bool operator!() const;
202 
203 
204  /*
205  * Returns the length of the vector
206  */
207  double length() const;
208 
209  /*
210  * Returns the unit vector
211  */
212  Vector3D unit() const;
213 
214  /*
215  * Returns the angle between this vector and that of another.
216  */
217  double angle(const Vector3D& vector_b) const;
218 
219  /**
220  * Returns dot product with another vector
221  */
222  double dot(const Vector3D& vector2) const;
223  double dot(const Point3D& point) const;
224 
225  /**
226  * Returns cross product with another vector
227  */
228  Vector3D cross(const Vector3D& vector2) const;
229 
230  enum class Colinearity {
231  UNDEFINED,
232  COLINEAR_PRO,
233  COLINEAR_ANTI,
234  NO
235  };
236  /**
237  * Returns whether the vector is colinear.
238  */
239  Colinearity colinear(const Vector3D& vector_b) const;
240 
241  /**
242  * Returns a vector rotated about another vector, which is used as the axis.
243  * @param angle - in radians to rotate.
244  * @param axis - vector which will be used as the axis through which it will be rotated.
245  */
246  Vector3D rotate_about(double angle, const Vector3D& axis) const;
247 
248  /**
249  * Returns a valid vector that has zero length.
250  */
251  static Vector3D zero_vector();
252 
253 };
254 
255 
256 
257 /*
258 * Point3D class is analagous to SUPoint3D struct, and holds the same variables.
259 *
260 * Class methods are given to allow easy vector mathematics.
261 *
262 * Point3D inherits from Vector3D, as the concept of a point and a vector is interchangeable in vector mathematics.
263 */
264 class Point3D {
265  private:
266  SUPoint3D m_point;
267  bool is_null = false; // Invalid flag
268  //constexpr static double EPSILON = 0.001; // Sketchup Tolerance is 1/1000"
269 
270  public:
271  constexpr static double EPSILON = 0.0005; // Sketchup Tolerance is 1/1000"
272  double &x;
273  double &y;
274  double &z;
275 
276  /**
277  * Invaid, or NULL Point3D objects can be simulated with this constructor.
278  */
279  Point3D();
280 
281  /**
282  * Constructs a NULL object, or a point with zero values as coordinates.
283  * @param valid - true for an object with zero values, or false for a null object.
284  */
285  Point3D(bool valid);
286 
287  /**
288  * Constructs a Point3D object from a SUPoint3D object.
289  * @param su_point - SUPoint3D object to be wrapped in this object.
290  */
291  Point3D(SUPoint3D su_point);
292 
293  /**
294  * Constructs a Point3D object from a SUVector3D object.
295  * @param su_vector - SUVector3D object to be converted to this object.
296  */
297  Point3D(SUVector3D su_vector);
298 
299  /**
300  * Constructs a Point3D object from given x y z coordinates.
301  * @param x - the X coordinate of the point.
302  * @param y - the Y coordinate of the point.
303  * @param z - the Z coordinate of the point.
304  */
305  Point3D(double x, double y, double z);
306 
307  /**
308  * Copy Constructor
309  */
310  Point3D(const Point3D& other);
311 
312  /**
313  * Allows conversion from Vector3D
314  */
315  explicit Point3D( const Vector3D& vector);
316 
317  /**
318  * Copy assignment operator
319  */
320  Point3D &operator=(const Point3D &point);
321 
322  /*
323  * Cast to SUPoint3D struct
324  */
325  operator SUPoint3D() const;
326  operator const SUPoint3D*() const;
327 
328  /*
329  * Cast to Vector3D
330  */
331  operator Vector3D() const;
332 
333  /**
334  * Arithmetic operator overloads
335  */
336  Point3D operator+(const Point3D &point) const;
337  Point3D operator+(const Vector3D &vector) const;
338  Point3D operator+(const SUPoint3D &point) const;
339  Vector3D operator-(const Point3D &point) const;
340  Point3D operator-(const Vector3D &vector) const;
341  Point3D operator-(const SUPoint3D &point) const;
342  Point3D operator*(const double &scalar) const;
343  Point3D operator/(const double &scalar) const;
344 
345  /**
346  * Comparative operators
347  */
348  bool operator!() const;
349 
350  friend bool operator==(const Point3D& lhs, const Point3D& rhs);
351  friend bool operator!=(const Point3D& lhs, const Point3D& rhs);
352 
353 
354  /**
355  * Returns intersection between two line segments. Each line segment is represented by a point and a vector.
356  * @param return_colinear - if line segments overlap, return the point at which line A first interacts. with line B. If set to false, a null point will be returned for overlapping lines.
357  * @return if intersection is found the point of intersection is returned. If no intersection exists, a null Point3D object is returned.
358  */
359  static Point3D intersection_between_lines(const Point3D& point_a, const Vector3D& vector_a, const Point3D& point_b, const Vector3D& vector_b, bool return_colinear = false);
360 
361  /**
362  * Returns the point of intersection between a line segment and a ray drawn from a point.
363  * @param point_a - start point of the line segment to intersect
364  * @param vector_a - vector to the end point of the line segment to intersect
365  * @param point_b - start point of the ray that will be intersected with the line.
366  * @param ray_b - the vector of the direction of the ray to intersect with the line.
367  * @param return_colinear - (optional) if the line and ray is collinear, setting this flag to false will mean no intersection will be returned. Otherwise, the first point at which the ray and line becomes colinear is returned.
368  * @return point representing the intersection. If there is no intersection, then a null point will be returned.
369  */
370  static Point3D ray_line_intersection(const Point3D& point_a, const Vector3D& vector_a, const Point3D& point_b, const Vector3D& ray_b, bool return_colinear = false);
371 
372 
373 };
374 
375 // Forward declaration
376 class Line3D;
377 /*
378 * Plane3D class is analagous to SUPlane3D struct, and holds the same variables.
379 *
380 * Class methods are included to allow easy vector mathematics.
381 */
382 class Plane3D {
383  private:
384  SUPlane3D m_plane;
385  bool is_null = false; // Invalid flag
386  constexpr static double EPSILON = 0.0005; // Sketchup Tolerance is 1/1000"
387 
388  public:
389  double &a;
390  double &b;
391  double &c;
392  double &d;
393 
394  Plane3D();
395  Plane3D(const SUPlane3D plane);
396  Plane3D(double a, double b, double c, double d);
397  Plane3D(const Face &face);
398 
399  /**
400  * Invaid, or NULL Plane3D objects can be simulated with this constructor.
401  */
402  Plane3D(bool invalid);
403 
404  /**
405  * Create a plane using a point and a vector.
406  */
407  Plane3D(const Vector3D& normal, const Point3D& point);
408  Plane3D(const Point3D& point, const Vector3D& normal);
409 
410  // Copy constructor
411  Plane3D(const Plane3D &plane);
412 
413  // Overload copy assignment operator
414  Plane3D &operator=(const Plane3D &plane);
415 
416  /**
417  * Implicit conversion to SUPlane3D
418  */
419  operator SUPlane3D() const;
420 
421  /**
422  * Comparative operators
423  */
424  bool operator!() const;
425 
426  friend bool operator==(const Plane3D& lhs, const Plane3D& rhs);
427  friend bool operator!=(const Plane3D& lhs, const Plane3D& rhs);
428 
429  /**
430  * Checks if geometry is on the plane
431  */
432  bool coplanar(const Plane3D& test_plane) const;
433 
434  /**
435  * Returns the normal of the plane
436  */
437  Vector3D normal() const;
438 
439  /**
440  * Returns line of intersection between two planes
441  */
442  Line3D intersection(const Plane3D& plane2) const;
443 
444  /**
445  * Returns point where a line intersects this plane.
446  */
447  Point3D intersection(const Line3D &line) const;
448 
449  /**
450  * Returns point where a ray drawn from the given point intersects this plane. Note that this is different from a line, which effectively draws a ray in both directions of the point.
451  * @param start_point - the point from which the ray will be drawn from.
452  * @param direction - vector representing the direction of the ray.
453  * @return point of the intersection, or a null Point3D object if no intersection exists.
454  */
455  Point3D intersection(const Point3D& start_point, const Vector3D& direction) const;
456 
457  /**
458  * Returns point at which a line segment drawn from point A to point B intersects the plane.
459  * @param point_a - the start of the line segment.
460  * @param point_b - the end of the line segment.
461  * @return point of the intersection, or a null Point3D object if no intersection exists.
462  */
463  Point3D intersection_between(const Point3D& point_a, const Point3D& point_b) const;
464 
465  double angle_with(const Plane3D& plane2) const;
466  double angle(const Plane3D& plane2) const { return angle_with(plane2);};
467 
468  /**
469  * Returns the distance of a point from the plane. It can be negative as the plane has a front and back side.
470  */
471  double distance(const Point3D& point) const;
472 
473  /**
474  * Returns true if the point is on the plane, within SketchUp's tolerance.
475  */
476  bool on_plane(const Point3D& point) const;
477 
478  /**
479  * Returns a plane moved along normal by given amount.
480  */
481  Plane3D offset(double offset_by) const;
482 
483  /**
484  * Checks if the plane is parallel with another.
485  */
486  bool parallel(const Plane3D& plane2) const;
487 
488 
489  /**
490  * Returns a Plane with normals reversed.
491  */
492  Plane3D inverse() const;
493 
494  /**
495  * Create a plane from a series of points (normally vertexes within a loop).
496  *
497  * Note that the normal of the returned plane (if successful) will point in the direction expected of an OUTER_LOOP.
498  */
499  static Plane3D plane_from_loop(const std::vector<Point3D>& loop_points);
500 };
501 
503  private:
504  SUBoundingBox3D m_bounding_box;
505  bool is_null = false; // Invalid flag
506 
507  public:
508  BoundingBox3D();
509  BoundingBox3D(SUBoundingBox3D bounding_box);
510 
511  /**
512  * Invalid, or NULL BoundingBox3D objects can be simulated with this constructor.
513  */
514  BoundingBox3D(bool valid);
515 
516  /** Casting overload */
517  operator SUBoundingBox3D() const;
518 
519  /**
520  * Comparative operators
521  */
522  bool operator!() const;
523 
524  /**
525  * Returns the point where x,y and z are at their minimum
526  */
527  Point3D min() const;
528 
529  /**
530  * Set the minimum point
531  */
532  void min_point(const Point3D& point);
533 
534  /**
535  * Returns the point where x,y and z are at their maximum
536  */
537  Point3D max() const;
538 
539  /**
540  * Set the maximum point
541  */
542  void max_point(const Point3D& point);
543 };
544 
545 
546 /**
547 * A Line3D represents a point and a vector, which carries on into infinity in two directions. There is no equivalent native object in the Sketchup C API.
548 */
549 class Line3D {
550  private:
551  Point3D m_point;
552  Vector3D m_direction;
553  bool is_null = false; // Invalid flag
554  constexpr static double EPSILON = 0.0005; // Sketchup Tolerance is 1/1000"
555 
556  public:
557  Line3D();
558  Line3D(const Point3D point, const Vector3D direction);
559  Line3D(const Vector3D direction, const Point3D point);
560 
561  /**
562  * Invaid, or NULL Line3D objects can be simulated with this constructor.
563  * @param valid - if true, a valid line will be created with a point and no direction.
564  */
565  Line3D(bool valid);
566 
567  /**
568  * Copy constructor
569  */
570  Line3D(const Line3D& other);
571 
572  Point3D &point;
573  Vector3D &direction;
574 
575  // Overload copy assignment operator
576  Line3D &operator=(const Line3D &line);
577 
578  /**
579  * Comparative operators
580  */
581  bool operator!() const;
582 
583  Point3D intersection(const Line3D &line) const;
584  Point3D intersection(const Plane3D &plane) const;
585 
586  /**
587  * Returns the intersection between this line and a line segment drawn between two points, given by a point and a vector from that point.
588  * @param point - point representing the start of the line segment.
589  * @param vector - vector representing the direction and length of the line segment from the start point.
590  * @return point3D object, representing the point of intersection. If there is no intersection between the line and the line segment, a null point3D object will be returned.
591  */
592  Point3D intersection(const Point3D& point, const Vector3D& vector) const;
593 
594 
595  /**
596  * Return the closest points on two lines.
597  * @param other_line the line with which to find the shortest.
598  * @return pair of Point3D objects representing the point (first) on this line, and the point (second) on the other line. If the lines are parallel, the point3D objects returned will be invalid.
599  */
600  std::pair<Point3D, Point3D> closest_points(const Line3D &line) const;
601 
602  /**
603  * Return the closest point on the line to the point.
604  * @param point - the point for which to find the shortest point on the line
605  * @return Point3D representing the point on this line, where it is closest to the target point.
606  */
607  Point3D closest_point(const Point3D& point) const;
608 
609  /**
610  * Return the closest distance between the line and the given point.
611  * @param point - the point for which to find the shortest distance to the line
612  * @return double distance between the point and line.
613  */
614  double distance(const Point3D& point) const;
615 
616  /**
617  * Check if point is on line.
618  */
619  bool on_line(const Point3D& point) const;
620 
621  /**
622  * Check if a point lies on a line segment.
623  * @param point_a - the start point of the line segment.
624  * @param point_b - the end point of the line segment.
625  * @param test_point - the point to test.
626  * @return true if the point lies between the line segment.
627  */
628  static bool on_line_segment(const Point3D& point_a, const Point3D& point_b, const Point3D& test_point);
629 
630  /**
631  * Returns true if the Line or vector given is parallel to this line.
632  */
633  bool parallel(const Line3D &line) const;
634  bool parallel(const Vector3D &vector) const;
635 
636  /**
637  * Compares two lines if they represent the same line.
638  */
639  friend bool operator==(const Line3D& lhs, const Line3D& rhs);
640 
641 };
642 
643 } /* namespace CW */
644 #endif /* Geometry_h */
Radians operator+(const double value) const
Definition: Geometry.cpp:79
double difference(const Radians &other) const
Definition: Geometry.cpp:113
Definition: Color.hpp:34
Radians & operator=(const Radians &radians)
Definition: Geometry.cpp:70