opennurbs_point.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 ////////////////////////////////////////////////////////////////
18 //
19 // defines double precision point, vector, and array classes
20 //
21 ////////////////////////////////////////////////////////////////
22 #if !defined(ON_POINT_INC_)
23 #define ON_POINT_INC_
24 
25 class ON_BoundingBox;
26 class ON_Xform;
27 class ON_Line;
28 class ON_Plane;
29 
30 class ON_2dPoint;
31 class ON_3dPoint;
32 class ON_4dPoint;
33 
34 class ON_2dVector;
35 class ON_3dVector;
36 
37 class ON_2fVector;
38 class ON_3fVector;
39 
40 class ON_Interval;
41 
42 ////////////////////////////////////////////////////////////////
43 //
44 // ON_Interval
45 //
46 class ON_CLASS ON_Interval
47 {
48 public:
49  static const ON_Interval EmptyInterval; // (ON_UNSET_VALUE,ON_UNSET_VALUE)
50  static const ON_Interval ZeroToOne; // (0.0, 1.0)
51  static const ON_Interval ZeroToTwoPi; // (0.0, 2.0*ON_PI)
52  static const ON_Interval Nan; // (ON_DBL_QNAN,ON_DBL_QNAN)
53 
54 public:
55  // The default constructor creates ON_Interval::EmptyInterval (ON_UNSET_VALUE,ON_UNSET_VALUE)
56  ON_Interval();
57  ~ON_Interval() = default;
58  ON_Interval(const ON_Interval&) = default;
59  ON_Interval& operator=(const ON_Interval&) = default;
60 
61  ON_Interval(double t0,double t1);
62 
63 public:
64  // Interval = (m_t[0], m_t[1])
65  double m_t[2];
66 
67 #if defined(OPENNURBS_WALL)
68  // Goal is to eventually require = as the only way to modify ON_Interval values.
69  ON_DEPRECATED_MSG("Use interval = ON_Interval::EmptyInterval;")
70 #endif
71  void Destroy();
72 
73  /*
74  Description:
75  Sets interval to [t0,t1]
76  Parameters:
77  t0 - [in]
78  t1 - [in]
79  See Also:
80  ON_Interval::ON_Interval( double, double )
81  */
82  void Set(
83  double t0,
84  double t1
85  );
86 
87  /*
88  Description:
89  Convert normalized parameter to interval value, or pair of values.
90  Parameters:
91  normalized_parameter - [in]
92  Returns:
93  Interval parameter
94  min*(1.0-normalized_parameter) + max*normalized_parameter
95  See Also:
96  ON_Interval::NormalizedParameterAt
97  */
98  double ParameterAt (
99  double normalized_parameter
100  ) const;
101  ON_Interval ParameterAt (
102  ON_Interval normalized_interval
103  ) const;
104 
105  /*
106  Description:
107  Convert interval value, or pair of values, to normalized parameter.
108  Parameters:
109  interval_parameter - [in] value in interval
110  Returns:
111  Normalized parameter x so that
112  min*(1.0-x) + max*x = interval_parameter.
113  See Also:
114  ON_Interval::ParameterAt
115  */
116  double NormalizedParameterAt (
117  double interval_parameter
118  ) const;
119  ON_Interval NormalizedParameterAt (
120  ON_Interval interval_parameter
121  ) const;
122 
123  double& operator[](int); // returns (index<=0) ? m_t[0] : m_t[1]
124  double operator[](int) const; // returns (index<=0) ? m_t[0] : m_t[1]
125  double& operator[](unsigned int); // returns (index<=0) ? m_t[0] : m_t[1]
126  double operator[](unsigned int) const; // returns (index<=0) ? m_t[0] : m_t[1]
127 
128  double Min() const; // returns smaller of m_t[0] and m_t[1]
129  double Max() const; // returns larger of m_t[0] and m_t[1]
130  double Mid() const; // returns 0.5*(m_t[0] + m_t[1])
131  double Length() const; // returns signed length, m_t[1]-m_t[0]
132 
133  bool IsIncreasing() const; // returns true if m_t[0] < m_t[1]
134  bool IsDecreasing() const; // returns true if m_t[0] > m_t[0];
135  bool IsInterval() const; // returns truc if m_t[0] != m_t[1]
136  bool IsSingleton() const; // returns true if m_t[0] == m_t[1] != ON_UNSET_VALUE
137  bool IsEmptyInterval() const; // returns true if m_t[0] == m_t[1] == ON_UNSET_VALUE
138  bool IsValid() const; // returns ON_IsValid(m_t[0]) && ON_IsValid(m_t[1])
139 
140 #if defined(OPENNURBS_WALL)
141  ON_DEPRECATED_MSG("Use IsEmptyInterval()")
142 #endif
143  bool IsEmptySet() const; // returns true if m_t[0] == m_t[1] == ON_UNSET_VALUE
144 
145  bool MakeIncreasing(); // returns true if resulting interval IsIncreasing()
146 
147  /*
148  Description:
149  A well ordered dictionary compare function that is nan aware and can
150  be used for robust sorting.
151  */
152  static int Compare(
153  const ON_Interval& lhs,
154  const ON_Interval& rhs
155  );
156 
157 
158  /*
159  Returns:
160  True if (lhs.m_t[0] != rhs.m_t[0]) or (lhs.m_t[1] != rhs.m_t[1]) and
161  no values are nans.
162  */
163  bool operator!=(const ON_Interval& rhs) const;
164 
165  /*
166  Returns:
167  True if (lhs.m_t[0] == rhs.m_t[0]) and (lhs.m_t[1] === rhs.m_t[1]).
168  */
169  bool operator==(const ON_Interval& rhs) const;
170 
171  /*
172  Description:
173  Test a value t to see if it is inside the interval.
174  Parameters:
175  t - [in] value to test
176  bTestOpenInterval - [in]
177  If false, t is tested to see if it satisfies min <= t <= max.
178  If true, t is tested to see if it satisfies min < t < max.
179  Returns:
180  true if t is in the interval and false if t is not
181  in the interval.
182  */
183  bool Includes(
184  double t,
185  bool bTestOpenInterval = false
186  ) const;
187 
188  /*
189  Description:
190  Test an interval to see if it is contained in this interval.
191  Parameters:
192  other - [in] interval to test
193  bProperSubSet - [in] if true, then the test is for a proper subinterval.
194  Returns:
195  If bProperSubSet is false, then the result is true when
196  this->Min() <= other.Min() and other.Max() <= this->Max().
197  If bProperSubSet is true, then the result is true when
198  this->Min() <= other.Min() and other.Max() <= this->Max()
199  and at least one of the inequalites is strict.
200  */
201  bool Includes(
202  const ON_Interval& other,
203  bool bProperSubSet = false
204  ) const;
205 
206  /*
207  Description:
208  Test a pair of interval to see if they have a non-empty intersection.
209  Parameters:
210  A - [in] interval to test
211  B - [in] interval to test
212  Returns:
213  true if the intersection is non-empty,
214  including if the intersection is a single point.
215  false otherwise.
216  */
217  static bool IntervalsOverlap(const ON_Interval& A, const ON_Interval& B);
218 
219  /*
220  Description:
221  Changes interval to [-m_t[1],-m_t[0]].
222  */
223  void Reverse();
224 
225  /*
226  Description:
227  Swaps m_t[0] and m_t[1].
228  */
229  void Swap();
230 
231  //////////
232  // If the intersection is not empty, then
233  // intersection = [max(this.Min(),arg.Min()), min(this.Max(),arg.Max())]
234  // Intersection() returns true if the intersection is not empty.
235  // The interval [ON_UNSET_VALUE,ON_UNSET_VALUE] is considered to be
236  // the empty set interval. The result of any intersection involving an
237  // empty set interval or disjoint intervals is the empty set interval.
238  bool Intersection( // this = this intersect arg
239  const ON_Interval&
240  );
241 
242  //////////
243  // If the intersection is not empty, then
244  // intersection = [max(argA.Min(),argB.Min()), min(argA.Max(),argB.Max())]
245  // Intersection() returns true if the intersection is not empty.
246  // The interval [ON_UNSET_VALUE,ON_UNSET_VALUE] is considered to be
247  // the empty set interval. The result of any intersection involving an
248  // empty set interval or disjoint intervals is the empty set interval.
249  bool Intersection( // this = intersection of two args
250  const ON_Interval&,
251  const ON_Interval&
252  );
253 
254  //////////
255  // The union of an empty set and an increasing interval is the increasing
256  // interval. The union of two empty sets is empty. The union of an empty
257  // set an a non-empty interval is the non-empty interval.
258  // The union of two non-empty intervals is
259  // union = [min(this.Min(),arg.Min()), max(this.Max(),arg.Max()),]
260  // Union() returns true if the union is not empty.
261  bool Union( // this = this union arg
262  const ON_Interval&
263  );
264 
265  bool Union( // this = this union arg
266  double t
267  );
268 
269  bool Union( // this = this union arg
270  int count,
271  const double* t
272  );
273 
274  //////////
275  // The union of an empty set and an increasing interval is the increasing
276  // interval. The union of two empty sets is empty. The union of an empty
277  // set an a non-empty interval is the non-empty interval.
278  // The union of two non-empty intervals is
279  // union = [min(argA.Min(),argB.Min()), max(argA.Max(),argB.Max()),]
280  // Union() returns true if the union is not empty.
281  bool Union( // this = union of two args
282  const ON_Interval&,
283  const ON_Interval&
284  );
285 };
286 
287 
288 ////////////////////////////////////////////////////////////////
289 //
290 // ON_2dPoint
291 //
292 class ON_CLASS ON_2dPoint
293 {
294 public:
295  double x, y;
296 
297 public:
298  // x,y not initialized
299  ON_2dPoint() = default;
300  ~ON_2dPoint() = default;
301  ON_2dPoint(const ON_2dPoint&) = default;
302  ON_2dPoint& operator=(const ON_2dPoint&) = default;
303 
304 public:
305  static const ON_2dPoint Origin; // (0.0,0.0)
306  static const ON_2dPoint UnsetPoint; // (ON_UNSET_VALUE,ON_UNSET_VALUE)
307  static const ON_2dPoint NanPoint; // (ON_DBL_QNAN,ON_DBL_QNAN)
308 
309  /*
310  Description:
311  A well ordered dictionary compare function that is nan aware and can
312  be used for robust sorting.
313  */
314  static int Compare(
315  const ON_2dPoint& lhs,
316  const ON_2dPoint& rhs
317  );
318 
319  explicit ON_2dPoint(double x,double y);
320 #if defined(OPENNURBS_WALL)
321  // Goal is to eventually have all constructors that discard informtion be explicit.
322  explicit
323 #endif
324  ON_2dPoint(const ON_3dPoint& ); // from 3d point
325 
326  explicit ON_2dPoint(const ON_4dPoint& h); // from 4d point - h.w must be non-zero
327  ON_2dPoint(const ON_2dVector& ); // from 2d vector
328  explicit ON_2dPoint(const ON_3dVector& ); // from 3d vector
329 
330  explicit ON_2dPoint(const double*); // from double[2] array
331 
332  ON_2dPoint(const class ON_2fPoint&); // from 2f point
333  explicit ON_2dPoint(const class ON_3fPoint&); // from 3f point
334  explicit ON_2dPoint(const class ON_4fPoint& h); // from 4f point - h.w must be non-zero
335  explicit ON_2dPoint(const class ON_2fVector&); // from 2f vector
336  explicit ON_2dPoint(const class ON_3fVector&); // from 3f vector
337 
338  explicit ON_2dPoint(const float*); // from float[2] array
339 
340  // (double*) conversion operators
341  operator double*();
342  operator const double*() const;
343 
344  // use implicit operator=(const ON_2dPoint&)
345  ON_2dPoint& operator=(const ON_3dPoint&);
346  ON_2dPoint& operator=(const ON_4dPoint&);
347  ON_2dPoint& operator=(const ON_2dVector&);
348  ON_2dPoint& operator=(const ON_3dVector&);
349  ON_2dPoint& operator=(const double*); // point = double[2] support
350 
351  ON_2dPoint& operator=(const ON_2fPoint&);
352  ON_2dPoint& operator=(const ON_3fPoint&);
353  ON_2dPoint& operator=(const ON_4fPoint&);
354  ON_2dPoint& operator=(const ON_2fVector&);
355  ON_2dPoint& operator=(const ON_3fVector&);
356  ON_2dPoint& operator=(const float*); // point = float[2] support
357 
358  ON_2dPoint& operator*=(double);
359  ON_2dPoint& operator/=(double);
360  ON_2dPoint& operator+=(const ON_2dVector&);
361  ON_2dPoint& operator-=(const ON_2dVector&);
362 
363  ON_2dPoint operator*(int) const;
364  ON_2dPoint operator/(int) const;
365  ON_2dPoint operator*(float) const;
366  ON_2dPoint operator/(float) const;
367  ON_2dPoint operator*(double) const;
368  ON_2dPoint operator/(double) const;
369 
370  ON_2dPoint operator+(const ON_2dPoint&) const;
371  ON_2dPoint operator+(const ON_2dVector&) const;
372  ON_2dVector operator-(const ON_2dPoint&) const;
373  ON_2dPoint operator-(const ON_2dVector&) const;
374  ON_3dPoint operator+(const ON_3dPoint&) const;
375  ON_3dPoint operator+(const ON_3dVector&) const;
376  ON_3dVector operator-(const ON_3dPoint&) const;
377  ON_3dPoint operator-(const ON_3dVector&) const;
378 
379  ON_2dPoint operator+(const ON_2fPoint&) const;
380  ON_2dPoint operator+(const ON_2fVector&) const;
381  ON_2dVector operator-(const ON_2fPoint&) const;
382  ON_2dPoint operator-(const ON_2fVector&) const;
383  ON_3dPoint operator+(const ON_3fPoint&) const;
384  ON_3dPoint operator+(const ON_3fVector&) const;
385  ON_3dVector operator-(const ON_3fPoint&) const;
386  ON_3dPoint operator-(const ON_3fVector&) const;
387 
388  double operator*(const ON_2dPoint&) const; // dot product for points acting as vectors
389  double operator*(const ON_2dVector&) const; // dot product for points acting as vectors
390 
391  ON_2dPoint operator*(const ON_Xform&) const;
392 
393  bool operator==(const ON_2dPoint&) const;
394  bool operator!=(const ON_2dPoint&) const;
395 
396  // dictionary order comparisons
397  bool operator<=(const ON_2dPoint&) const;
398  bool operator>=(const ON_2dPoint&) const;
399  bool operator<(const ON_2dPoint&) const;
400  bool operator>(const ON_2dPoint&) const;
401 
402  // index operators mimic double[2] behavior
403  double& operator[](int);
404  double operator[](int) const;
405  double& operator[](unsigned int);
406  double operator[](unsigned int) const;
407 
408  /*
409  Returns:
410  False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
411  */
412  bool IsValid() const;
413 
414  /*
415  Returns:
416  True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
417  */
418  bool IsUnset() const;
419 
420  // set 2d point value
421  void Set(double x,double y);
422 
423  double DistanceTo( const ON_2dPoint& ) const;
424 
425  int MaximumCoordinateIndex() const;
426  double MaximumCoordinate() const; // absolute value of maximum coordinate
427 
428  int MinimumCoordinateIndex() const;
429  double MinimumCoordinate() const; // absolute value of minimum coordinate
430 
431  ON_DEPRECATED_MSG("Use p = ON_2dPoint::Origin;")
432  void Zero(); // set all coordinates to zero;
433 
434  /*
435  Returns:
436  true if all coordinates are not zero and no coordinates are nans.
437  false otherwise.
438  */
439  bool IsZero() const;
440 
441  /*
442  Returns:
443  true if at lease one coordinate is not zero and no coordinates are nans.
444  */
445  bool IsNotZero() const;
446 
447  // These transform the point in place. The transformation matrix acts on
448  // the left of the point; i.e., result = transformation*point
449  void Transform(
450  const ON_Xform&
451  );
452 
453  void Rotate( // rotatation in XY plane
454  double angle, // angle in radians
455  const ON_2dPoint& center // center of rotation
456  );
457 
458  void Rotate( // rotatation in XY plane
459  double sin_angle, // sin(angle)
460  double cos_angle, // cos(angle)
461  const ON_2dPoint& center // center of rotation
462  );
464  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
465 };
466 
467 ON_DECL
468 ON_2dPoint operator*(int, const ON_2dPoint&);
469 
470 ON_DECL
471 ON_2dPoint operator*(float, const ON_2dPoint&);
472 
473 ON_DECL
474 ON_2dPoint operator*(double, const ON_2dPoint&);
476 ////////////////////////////////////////////////////////////////
477 //
478 // ON_3dPoint
479 //
480 class ON_CLASS ON_3dPoint
481 {
482 public:
483  double x, y, z;
484 
485 public:
486  // x,y,z not initialized
487  ON_3dPoint() = default;
488  ~ON_3dPoint() = default;
489  ON_3dPoint(const ON_3dPoint&) = default;
490  ON_3dPoint& operator=(const ON_3dPoint&) = default;
491 
492 public:
493  static const ON_3dPoint Origin; // (0.0,0.0,0.0)
494  static const ON_3dPoint UnsetPoint; // (ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE)
495  static const ON_3dPoint NanPoint; // (ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN)
496 
497  /*
498  Description:
499  A well ordered dictionary compare function that is nan aware and can
500  be used for robust sorting.
501  */
502  static int Compare(
503  const ON_3dPoint& lhs,
504  const ON_3dPoint& rhs
505  );
506 
507 public:
508  explicit ON_3dPoint(double x,double y,double z);
509 #if defined(OPENNURBS_WALL)
510  // Goal is to eventually have all constructors that discard informtion be explicit.
511  explicit
512 #endif
513  ON_3dPoint(const ON_2dPoint& ); // from 2d point
514  explicit ON_3dPoint(const ON_4dPoint& h); // from 4d point - h.w must be non-zero
515  explicit ON_3dPoint(const ON_2dVector& ); // from 2d vector
516  ON_3dPoint(const ON_3dVector& ); // from 3d vector
517  explicit ON_3dPoint(const double*); // from double[3] array
518 
519  explicit ON_3dPoint(const class ON_2fPoint&); // from 2f point
520  ON_3dPoint(const class ON_3fPoint&); // from 3f point
521  explicit ON_3dPoint(const class ON_4fPoint& h ); // from 4f point- h.w must be non-zero
522  explicit ON_3dPoint(const class ON_2fVector&); // from 2f point
523  explicit ON_3dPoint(const class ON_3fVector&); // from 3f point
524  explicit ON_3dPoint(const float*); // from float[3] array
525 
526  // (double*) conversion operators
527  operator double*();
528  operator const double*() const;
529 
530  // use implicit operator=(const ON_3dPoint&)
531  ON_3dPoint& operator=(const ON_2dPoint&);
532  ON_3dPoint& operator=(const ON_4dPoint&);
533  ON_3dPoint& operator=(const ON_2dVector&);
534  ON_3dPoint& operator=(const ON_3dVector&);
535  ON_3dPoint& operator=(const double*); // point = double[3] support
536 
537  ON_3dPoint& operator=(const class ON_2fPoint&);
538  ON_3dPoint& operator=(const class ON_3fPoint&);
539  ON_3dPoint& operator=(const class ON_4fPoint&);
540  ON_3dPoint& operator=(const class ON_2fVector&);
541  ON_3dPoint& operator=(const class ON_3fVector&);
542  ON_3dPoint& operator=(const float*); // point = float[3] support
543 
544  ON_3dPoint& operator*=(double);
545  ON_3dPoint& operator/=(double);
546  ON_3dPoint& operator+=(const ON_3dVector&);
547  ON_3dPoint& operator-=(const ON_3dVector&);
548 
549  ON_3dPoint operator*(int) const;
550  ON_3dPoint operator/(int) const;
551  ON_3dPoint operator*(float) const;
552  ON_3dPoint operator/(float) const;
553  ON_3dPoint operator*(double) const;
554  ON_3dPoint operator/(double) const;
555 
556  ON_3dPoint operator+(const ON_3dPoint&) const;
557  ON_3dPoint operator+(const ON_3dVector&) const;
558  ON_3dVector operator-(const ON_3dPoint&) const;
559  ON_3dPoint operator-(const ON_3dVector&) const;
560  ON_3dPoint operator+(const ON_2dPoint&) const;
561  ON_3dPoint operator+(const ON_2dVector&) const;
562  ON_3dVector operator-(const ON_2dPoint&) const;
563  ON_3dPoint operator-(const ON_2dVector&) const;
564 
565  ON_3dPoint operator+(const ON_3fPoint&) const;
566  ON_3dPoint operator+(const ON_3fVector&) const;
567  ON_3dVector operator-(const ON_3fPoint&) const;
568  ON_3dPoint operator-(const ON_3fVector&) const;
569  ON_3dPoint operator+(const ON_2fPoint&) const;
570  ON_3dPoint operator+(const ON_2fVector&) const;
571  ON_3dVector operator-(const ON_2fPoint&) const;
572  ON_3dPoint operator-(const ON_2fVector&) const;
573 
574  double operator*(const ON_3dPoint&) const; // dot product for points acting as vectors
575  double operator*(const ON_3dVector&) const; // dot product for points acting as vectors
576 
577  ON_3dPoint operator*(const ON_Xform&) const;
578 
579  bool operator==(const ON_3dPoint&) const;
580  bool operator!=(const ON_3dPoint&) const;
581 
582  // dictionary order comparisons
583  bool operator<=(const ON_3dPoint&) const;
584  bool operator>=(const ON_3dPoint&) const;
585  bool operator<(const ON_3dPoint&) const;
586  bool operator>(const ON_3dPoint&) const;
587 
588  // index operators mimic double[3] behavior
589  double& operator[](int);
590  double operator[](int) const;
591  double& operator[](unsigned int);
592  double operator[](unsigned int) const;
593 
594  /*
595  Returns:
596  False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
597  */
598  bool IsValid() const;
599 
600  /*
601  Returns:
602  True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
603  */
604  bool IsUnset() const;
605 
606  // set 3d point value
607  void Set(double x,double y,double z);
608 
609  double DistanceTo( const ON_3dPoint& ) const;
610 
611  int MaximumCoordinateIndex() const;
612  double MaximumCoordinate() const; // absolute value of maximum coordinate
613 
614  int MinimumCoordinateIndex() const;
615  double MinimumCoordinate() const; // absolute value of minimum coordinate
616 
617  double Fuzz( double tolerance = ON_ZERO_TOLERANCE ) const; // tolerance to use when comparing 3d points
618 
619 #if defined(OPENNURBS_WALL)
620  // Goal is to eventually remove all functions that modify points in place.
621  ON_DEPRECATED_MSG("Use p = ON_3dPoint::Origin;")
622 #endif
623  void Zero(); // set all coordinates to zero;
624 
625  /*
626  Returns:
627  true if all coordinates are not zero and no coordinates are nans.
628  false otherwise.
629  */
630  bool IsZero() const;
631 
632  /*
633  Returns:
634  true if at lease one coordinate is not zero and no coordinates are nans.
635  */
636  bool IsNotZero() const;
637 
638  // These transform the point in place. The transformation matrix acts on
639  // the left of the point; i.e., result = transformation*point
640  void Transform(
641  const ON_Xform&
642  );
643 
644  void Rotate(
645  double angle, // angle in radians
646  const ON_3dVector& axis, // axis of rotation
647  const ON_3dPoint& center // center of rotation
648  );
649 
650  void Rotate(
651  double sin_angle, // sin(angle)
652  double cos_angle, // cos(angle)
653  const ON_3dVector& axis, // axis of rotation
654  const ON_3dPoint& center // center of rotation
655  );
656 
657  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
658 };
659 
660 ON_DECL
661 ON_3dPoint operator*(int, const ON_3dPoint&);
662 
663 ON_DECL
664 ON_3dPoint operator*(float, const ON_3dPoint&);
665 
666 ON_DECL
667 ON_3dPoint operator*(double, const ON_3dPoint&);
668 
669 ////////////////////////////////////////////////////////////////
670 //
671 // ON_4dPoint (homogeneous coordinates)
672 //
673 class ON_CLASS ON_4dPoint
674 {
675 public:
676  double x, y, z, w;
677 
678  /*
679  Returns:
680  ON_UNSET_VALUE, if x or w is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
681  and neither x nor w is a nan.
682  x/w, otherwise
683  Remarks:
684  If w is 0.0 or nan, the result will be a nan.
685  */
686  double EuclideanX() const;
687 
688  /*
689  Returns:
690  ON_UNSET_VALUE, if y or w is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
691  and neither y nor w is a nan.
692  y/w, otherwise
693  Remarks:
694  If w is 0.0 or nan, the result will be a nan.
695  */
696  double EuclideanY() const;
697 
698  /*
699  Returns:
700  ON_UNSET_VALUE, if z or w is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
701  and neither z nor w is a nan.
702  z/w, otherwise
703  Remarks:
704  If w is 0.0 or nan, the result will be a nan.
705  */
706  double EuclideanZ() const;
707 
708 public:
709  // x,y,z,w not initialized
710  ON_4dPoint() = default;
711  ~ON_4dPoint() = default;
712  ON_4dPoint(const ON_4dPoint&) = default;
713  ON_4dPoint& operator=(const ON_4dPoint&) = default;
714 
715 public:
716  static const ON_4dPoint Zero; // (0,0,0,0)
717  static const ON_4dPoint Nan; // (ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN)
718 
719  explicit ON_4dPoint(double x,double y,double z,double w);
720 
721  // These constructors are not explicit because no informtion is lost.
722  ON_4dPoint(const ON_2dPoint& ); // from 2d point (z,y,0,1)
723  ON_4dPoint(const ON_3dPoint& ); // from 3d point (x,y,z,1)
724  ON_4dPoint(const ON_2dVector& ); // from 2d vector (x,y,0,0)
725  ON_4dPoint(const ON_3dVector& ); // from 3d vector (x,y,z,0)
726 
727  explicit ON_4dPoint(const double*); // from double[4] array
728 
729  // These constructors are not explicit because no informtion is lost.
730  ON_4dPoint(const ON_2fPoint& ); // from 2f point (z,y,0,1)
731  ON_4dPoint(const ON_3fPoint& ); // from 3f point (x,y,z,1)
732  ON_4dPoint(const ON_4fPoint& ); // from 4f point
733  ON_4dPoint(const ON_2fVector& ); // from 2f vector (z,y,0,0)
734  ON_4dPoint(const ON_3fVector& ); // from 3f vector (x,y,z,0)
735 
736  explicit ON_4dPoint(const float*); // from float[4] array
737 
738  /*
739  Description:
740  This function is provided because in rare cases it makes sense.
741  If you are not certian why you want this value, think carefully
742  or work with vectors and points in Euclidean coordinates.
743  Returns:
744  lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
745  Remark:
746  It is intentional that there is no operator* override for ON_4dPoint.
747  This intentional omission helps people pause and think before calling
748  ON_4dPoint::InnerProduct().
749  */
750  static double InnerProduct(
751  const ON_4dPoint& lhs,
752  const ON_4dPoint& rhs
753  );
754 
755  // (double*) conversion operators
756  operator double*();
757  operator const double*() const;
758 
759  // use implicit operator=(const ON_4dPoint&)
760  ON_4dPoint& operator=(const ON_2dPoint&);
761  ON_4dPoint& operator=(const ON_3dPoint&);
762  ON_4dPoint& operator=(const ON_2dVector&);
763  ON_4dPoint& operator=(const ON_3dVector&);
764  ON_4dPoint& operator=(const double*); // point = double[4] support
765 
766  ON_4dPoint& operator=(const class ON_2fPoint&);
767  ON_4dPoint& operator=(const class ON_3fPoint&);
768  ON_4dPoint& operator=(const class ON_4fPoint&);
769  ON_4dPoint& operator=(const class ON_2fVector&);
770  ON_4dPoint& operator=(const class ON_3fVector&);
771  ON_4dPoint& operator=(const float*); // point = float[4] support
772 
773  ON_4dPoint& operator*=(double);
774  ON_4dPoint& operator/=(double);
775  ON_4dPoint& operator+=(const ON_4dPoint&); // sum w = sqrt(|w1*w2|)
776  ON_4dPoint& operator-=(const ON_4dPoint&); // difference w = sqrt(|w1*w2|)
777 
778  ON_4dPoint operator*(double) const;
779  ON_4dPoint operator/(double) const;
780  ON_4dPoint operator+(const ON_4dPoint&) const; // sum w = sqrt(|w1*w2|)
781  ON_4dPoint operator-(const ON_4dPoint&) const; // difference w = sqrt(|w1*w2|)
782 
783  ON_4dPoint operator*(const ON_Xform&) const;
784 
785  /*
786  Description:
787  A well ordered projective compare function that is nan aware and can
788  be used for robust sorting.
789  Remarks:
790  double c = non-nan value.
791  ON_4dPoint h0 = ...;
792  ON_4dPoint h1(c*h0.x,c*h0.x,c*h0.x,c*h0.x);
793  0 == ON_4dPoint::ProjectiveCompare(h0,ha);
794  */
795  static int ProjectiveCompare(
796  const ON_4dPoint& lhs,
797  const ON_4dPoint& rhs
798  );
799 
800  /*
801  Description:
802  A well ordered dictionary compare function that is nan aware and can
803  be used for robust sorting.
804  */
805  static int DictionaryCompare(
806  const ON_4dPoint& lhs,
807  const ON_4dPoint& rhs
808  );
809 
810  /*
811  Returns:
812  True if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w).
813  */
814  bool operator==(const ON_4dPoint& rhs) const;
815 
816  /*
817  Returns:
818  True if lhs.* != rhs.* for some coordinate and no values are nans.
819  */
820  bool operator!=(const ON_4dPoint& rhs) const;
821 
822 public:
823  // index operators mimic double[4] behavior
824  double& operator[](int);
825  double operator[](int) const;
826  double& operator[](unsigned int);
827  double operator[](unsigned int) const;
828 
829  /*
830  Returns:
831  False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
832  */
833  bool IsValid() const;
834 
835  /*
836  Returns:
837  True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
838  */
839  bool IsUnset() const;
840 
841  // set 4d point value
842  void Set(double x,double y,double z,double w);
843 
844  int MaximumCoordinateIndex() const;
845  double MaximumCoordinate() const; // absolute value of maximum coordinate
846 
847  int MinimumCoordinateIndex() const;
848  double MinimumCoordinate() const; // absolute value of minimum coordinate
849 
850  bool Normalize(); // set so x^2 + y^2 + z^2 + w^2 = 1
851 
852  // These transform the point in place. The transformation matrix acts on
853  // the left of the point; i.e., result = transformation*point
854  void Transform(
855  const ON_Xform&
856  );
857 
858  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
859 };
860 
861 ON_DECL
862 ON_4dPoint operator*(double, const ON_4dPoint&);
863 
864 ////////////////////////////////////////////////////////////////
865 //
866 // ON_2dVector
867 //
868 class ON_CLASS ON_2dVector
869 {
870 public:
871  double x, y;
872 
873 public:
874  // x,y not initialized
875  ON_2dVector() = default;
876  ~ON_2dVector() = default;
877  ON_2dVector(const ON_2dVector&) = default;
878  ON_2dVector& operator=(const ON_2dVector&) = default;
879 
880 public:
881  static const ON_2dVector ZeroVector; // (0.0,0.0)
882  static const ON_2dVector XAxis; // (1.0,0.0)
883  static const ON_2dVector YAxis; // (0.0,1.0)
884  static const ON_2dVector UnsetVector; // (ON_UNSET_VALUE,ON_UNSET_VALUE)
885  static const ON_2dVector NanVector; // (ON_DBL_QNAN,ON_DBL_QNAN)
886 
887  /*
888  Description:
889  A well ordered dictionary compare function that is nan aware and can
890  be used for robust sorting.
891  */
892  static int Compare(
893  const ON_2dVector& lhs,
894  const ON_2dVector& rhs
895  );
896 
897  // Description:
898  // A index driven function to get unit axis vectors.
899  // Parameters:
900  // index - [in] 0 returns (1,0), 1 returns (0,1)
901  // Returns:
902  // Unit 2d vector with vector[i] = (i==index)?1:0;
903  static const ON_2dVector& UnitVector(
904  int // index
905  );
906 
907  explicit ON_2dVector(double x,double y);
908 
909  explicit ON_2dVector(const ON_3dVector& ); // from 3d vector
910  ON_2dVector(const ON_2dPoint& ); // from 2d point
911  explicit ON_2dVector(const ON_3dPoint& ); // from 3d point
912  explicit ON_2dVector(const double*); // from double[2] array
913 
914  ON_2dVector(const ON_2fVector& ); // from 2f vector
915  explicit ON_2dVector(const ON_3fVector& ); // from 3f vector
916  explicit ON_2dVector(const ON_2fPoint& ); // from 2f point
917  explicit ON_2dVector(const ON_3fPoint& ); // from 3f point
918  explicit ON_2dVector(const float*); // from double[2] array
919 
920  // (double*) conversion operators
921  operator double*();
922  operator const double*() const;
923 
924  // use implicit operator=(const ON_2dVector&)
925  ON_2dVector& operator=(const ON_3dVector&);
926  ON_2dVector& operator=(const ON_2dPoint&);
927  ON_2dVector& operator=(const ON_3dPoint&);
928  ON_2dVector& operator=(const double*); // vector = double[2] support
929 
930  ON_2dVector& operator=(const ON_2fVector&);
931  ON_2dVector& operator=(const ON_3fVector&);
932  ON_2dVector& operator=(const ON_2fPoint&);
933  ON_2dVector& operator=(const ON_3fPoint&);
934  ON_2dVector& operator=(const float*); // vector = float[2] support
935 
936  ON_2dVector operator-() const;
937 
938  ON_2dVector& operator*=(double);
939  ON_2dVector& operator/=(double);
940  ON_2dVector& operator+=(const ON_2dVector&);
941  ON_2dVector& operator-=(const ON_2dVector&);
942  // DO NOT ADD ANY MORE overrides of += or -=
943 
944  double operator*(const ON_2dVector&) const; // inner (dot) product
945  double operator*(const ON_2dPoint&) const; // inner (dot) product (point acting as vector)
946  double operator*(const ON_2fVector&) const; // inner (dot) product
947 
948  ON_2dVector operator*(int) const;
949  ON_2dVector operator/(int) const;
950  ON_2dVector operator*(float) const;
951  ON_2dVector operator/(float) const;
952  ON_2dVector operator*(double) const;
953  ON_2dVector operator/(double) const;
954 
955  ON_2dVector operator+(const ON_2dVector&) const;
956  ON_2dPoint operator+(const ON_2dPoint&) const;
957  ON_2dVector operator-(const ON_2dVector&) const;
958  ON_2dPoint operator-(const ON_2dPoint&) const;
959  ON_3dVector operator+(const ON_3dVector&) const;
960  ON_3dPoint operator+(const ON_3dPoint&) const;
961  ON_3dVector operator-(const ON_3dVector&) const;
962  ON_3dPoint operator-(const ON_3dPoint&) const;
963 
964  ON_2dVector operator+(const ON_2fVector&) const;
965  ON_2dPoint operator+(const ON_2fPoint&) const;
966  ON_2dVector operator-(const ON_2fVector&) const;
967  ON_2dPoint operator-(const ON_2fPoint&) const;
968  ON_3dVector operator+(const ON_3fVector&) const;
969  ON_3dPoint operator+(const ON_3fPoint&) const;
970  ON_3dVector operator-(const ON_3fVector&) const;
971  ON_3dPoint operator-(const ON_3fPoint&) const;
972 
973  ON_2dVector operator*(const ON_Xform&) const;
974 
975  bool operator==(const ON_2dVector&) const;
976  bool operator!=(const ON_2dVector&) const;
977 
978  // dictionary order comparisons
979  bool operator<=(const ON_2dVector&) const;
980  bool operator>=(const ON_2dVector&) const;
981  bool operator<(const ON_2dVector&) const;
982  bool operator>(const ON_2dVector&) const;
983 
984  // index operators mimic double[2] behavior
985  double& operator[](int);
986  double operator[](int) const;
987  double& operator[](unsigned int);
988  double operator[](unsigned int) const;
989 
990  /*
991  Returns:
992  False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
993  */
994  bool IsValid() const;
995 
996  /*
997  Returns:
998  True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
999  */
1000  bool IsUnset() const;
1001 
1002  // set 2d vector value
1003  void Set(double x,double y);
1004 
1005  int MaximumCoordinateIndex() const;
1006  double MaximumCoordinate() const; // absolute value of maximum coordinate
1007 
1008  int MinimumCoordinateIndex() const;
1009  double MinimumCoordinate() const; // absolute value of minimum coordinate
1010 
1011  double LengthSquared() const;
1012  double Length() const;
1013 
1014  // Signed area of the parallelagram. The volume element.
1015  // returns x*B.y - y*B.x
1016  double WedgeProduct(const ON_2dVector& B) const;
1017 
1018  bool Decompose( // Computes a, b such that this vector = a*X + b*Y
1019  // Returns false if unable to solve for a,b. This happens
1020  // when X,Y is not really a basis.
1021  //
1022  // If X,Y is known to be an orthonormal frame,
1023  // then a = V*X, b = V*Y will compute
1024  // the same result more quickly.
1025  const ON_2dVector&, // X
1026  const ON_2dVector&, // Y
1027  double*, // a
1028  double* // b
1029  ) const;
1030 
1031  int IsParallelTo(
1032  // returns 1: this and other vectors are parallel
1033  // -1: this and other vectors are anti-parallel
1034  // 0: this and other vectors are not parallel
1035  // or at least one of the vectors is zero
1036  const ON_2dVector& other, // other vector
1037  double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
1038  ) const;
1039 
1040  bool IsPerpendicularTo(
1041  // returns true: this and other vectors are perpendicular
1042  // false: this and other vectors are not perpendicular
1043  // or at least one of the vectors is zero
1044  const ON_2dVector& other, // other vector
1045  double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
1046  ) const;
1047 
1048  ON_DEPRECATED_MSG("Use v = ON_2dVector::ZeroVector;")
1049  void Zero(); // set all coordinates to zero;
1050 
1051  ON_DEPRECATED_MSG("Use v = -v;")
1052  void Reverse(); // negate all coordinates
1053 
1054  bool Unitize(); // returns false if vector has zero length
1055 
1056  /*
1057  Returns:
1058  If this is a valid non-zero vector, a unit vector parallel to this is returned.
1059  Otherwise the zero vector is returned.
1060  */
1061  ON_2dVector UnitVector() const;
1062 
1063 
1064  // Description:
1065  // Test a vector to see if it is very short
1066  //
1067  // Parameters:
1068  // tiny_tol - [in] (default = ON_ZERO_TOLERANCE) a nonzero
1069  // value used as the coordinate zero tolerance.
1070  //
1071  // Returns:
1072  // ( fabs(x) <= tiny_tol && fabs(y) <= tiny_tol )
1073  //
1074  bool IsTiny(
1075  double tiny_tol = ON_ZERO_TOLERANCE // tiny_tol
1076  ) const;
1077 
1078  // Returns:
1079  // true if vector is the zero vector.
1080  bool IsZero() const;
1081 
1082  /*
1083  Returns:
1084  true if at lease one coordinate is not zero and no coordinates are nans.
1085  */
1086  bool IsNotZero() const;
1087 
1088  // Returns:
1089  // true if vector is valid and has length 1.
1090  bool IsUnitVector() const;
1091 
1092  // set this vector to be perpendicular to another vector
1093  bool PerpendicularTo( // Result is not unitized.
1094  // returns false if input vector is zero
1095  const ON_2dVector&
1096  );
1097 
1098  // set this vector to be perpendicular to a line defined by 2 points
1099  bool PerpendicularTo(
1100  const ON_2dPoint&,
1101  const ON_2dPoint&
1102  );
1103 
1104  // These transform the vector in place. The transformation matrix acts on
1105  // the left of the vector; i.e., result = transformation*vector
1106  void Transform(
1107  const ON_Xform& // can use ON_Xform here
1108  );
1109 
1110  void Rotate(
1111  double angle // angle in radians
1112  );
1113 
1114  void Rotate(
1115  double sin_angle, // sin(angle)
1116  double cos_angle // cos(angle)
1117  );
1118 
1119  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
1120 };
1121 
1122 ON_DECL
1123 ON_2dVector operator*(int, const ON_2dVector&);
1124 
1125 ON_DECL
1126 ON_2dVector operator*(float, const ON_2dVector&);
1127 
1128 ON_DECL
1129 ON_2dVector operator*(double, const ON_2dVector&);
1130 
1131 ///////////////////////////////////////////////////////////////
1132 //
1133 // ON_2dVector utilities
1134 //
1135 
1136 ON_DECL
1137 double
1138 ON_DotProduct(
1139  const ON_2dVector&,
1140  const ON_2dVector&
1141  );
1142 
1143 ON_DECL
1144 ON_3dVector
1145 ON_CrossProduct(
1146  const ON_2dVector&,
1147  const ON_2dVector&
1148  );
1149 
1150 ON_DECL
1151 double
1152 ON_WedgeProduct( // signed area of the parallelagram. Volume element.
1153  const ON_2dVector& A, // returns A.x * B.y - A.y * B.x
1154  const ON_2dVector& B
1155  );
1156 
1157 ON_DECL
1158 bool
1159 ON_IsOrthogonalFrame( // true if X, Y are nonzero and mutually perpendicular
1160  const ON_2dVector&, // X
1161  const ON_2dVector& // Y
1162  );
1163 
1164 ON_DECL
1165 bool
1166 ON_IsOrthonormalFrame( // true if X, Y are orthogonal and unit length
1167  const ON_2dVector&, // X
1168  const ON_2dVector& // Y
1169  );
1171 ON_DECL
1172 bool
1173 ON_IsRightHandFrame( // true if X, Y are orthonormal and right handed
1174  const ON_2dVector&, // X
1175  const ON_2dVector& // Y
1176  );
1177 
1178 ////////////////////////////////////////////////////////////////
1179 //
1180 // ON_3dVector
1181 //
1182 class ON_CLASS ON_3dVector
1183 {
1184 public:
1185  double x, y, z;
1186 
1187 public:
1188  // x,y,z not initialized
1189  ON_3dVector() = default;
1190  ~ON_3dVector() = default;
1191  ON_3dVector(const ON_3dVector&) = default;
1192  ON_3dVector& operator=(const ON_3dVector&) = default;
1193 
1194 public:
1195  static const ON_3dVector ZeroVector; // (0.0,0.0,0.0)
1196  static const ON_3dVector XAxis; // (1.0,0.0,0.0)
1197  static const ON_3dVector YAxis; // (0.0,1.0,0.0)
1198  static const ON_3dVector ZAxis; // (0.0,0.0,1.0)
1199  static const ON_3dVector UnsetVector; // (ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE)
1200  static const ON_3dVector NanVector; // (ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN)
1201 
1202  /*
1203  Description:
1204  A well ordered dictionary compare function that is nan aware and can
1205  be used for robust sorting.
1206  */
1207  static int Compare(
1208  const ON_3dVector& lhs,
1209  const ON_3dVector& rhs
1210  );
1211 
1212  // Description:
1213  // A index driven function to get unit axis vectors.
1214  // Parameters:
1215  // index - [in] 0 returns (1,0,0), 1 returns (0,1,0),
1216  // 2 returns (0,0,1)
1217  // Returns:
1218  // Unit 3d vector with vector[i] = (i==index)?1:0;
1219  static const ON_3dVector& UnitVector(
1220  int // index
1221  );
1222 
1223  explicit ON_3dVector(double x,double y,double z);
1224 #if defined(OPENNURBS_WALL)
1225  // Goal is to eventually have all constructors that change dimension be explicit.
1226  explicit
1227 #endif
1228  ON_3dVector(const ON_2dVector& ); // from 2d vector
1229  explicit ON_3dVector(const ON_2dPoint& ); // from 2d point
1230  ON_3dVector(const ON_3dPoint& ); // from 3d point
1231  explicit ON_3dVector(const double*); // from double[3] array
1232 
1233  explicit ON_3dVector(const ON_2fVector& ); // from 2f vector
1234  ON_3dVector(const ON_3fVector& ); // from 3f vector
1235  explicit ON_3dVector(const ON_2fPoint& ); // from 2f point
1236  explicit ON_3dVector(const ON_3fPoint& ); // from 3f point
1237  explicit ON_3dVector(const float*); // from float[3] array
1238 
1239  // (double*) conversion operators
1240  operator double*();
1241  operator const double*() const;
1242 
1243  // use implicit operator=(const ON_3dVector&)
1244  ON_3dVector& operator=(const ON_2dVector&);
1245  ON_3dVector& operator=(const ON_2dPoint&);
1246  ON_3dVector& operator=(const ON_3dPoint&);
1247  ON_3dVector& operator=(const double*); // vector = double[3] support
1248 
1249  ON_3dVector& operator=(const ON_2fVector&);
1250  ON_3dVector& operator=(const ON_3fVector&);
1251  ON_3dVector& operator=(const ON_2fPoint&);
1252  ON_3dVector& operator=(const ON_3fPoint&);
1253  ON_3dVector& operator=(const float*); // vector = float[3] support
1254 
1255  ON_3dVector operator-() const;
1256 
1257  ON_3dVector& operator*=(double);
1258  ON_3dVector& operator/=(double);
1259  ON_3dVector& operator+=(const ON_3dVector&);
1260  ON_3dVector& operator-=(const ON_3dVector&);
1261  // DO NOT ADD ANY MORE overrides of += or -=
1262 
1263  double operator*(const ON_3dVector&) const; // inner (dot) product
1264  double operator*(const ON_3dPoint&) const; // inner (dot) product
1265  double operator*(const ON_3fVector&) const; // inner (dot) product
1266 
1267  ON_3dVector operator*(int) const;
1268  ON_3dVector operator/(int) const;
1269  ON_3dVector operator*(float) const;
1270  ON_3dVector operator/(float) const;
1271  ON_3dVector operator*(double) const;
1272  ON_3dVector operator/(double) const;
1273 
1274  ON_3dVector operator+(const ON_3dVector&) const;
1275  ON_3dPoint operator+(const ON_3dPoint&) const;
1276  ON_3dVector operator-(const ON_3dVector&) const;
1277  ON_3dPoint operator-(const ON_3dPoint&) const;
1278  ON_3dVector operator+(const ON_2dVector&) const;
1279  ON_3dPoint operator+(const ON_2dPoint&) const;
1280  ON_3dVector operator-(const ON_2dVector&) const;
1281  ON_3dPoint operator-(const ON_2dPoint&) const;
1282 
1283  ON_3dVector operator+(const ON_3fVector&) const;
1284  ON_3dPoint operator+(const ON_3fPoint&) const;
1285  ON_3dVector operator-(const ON_3fVector&) const;
1286  ON_3dPoint operator-(const ON_3fPoint&) const;
1287  ON_3dVector operator+(const ON_2fVector&) const;
1288  ON_3dPoint operator+(const ON_2fPoint&) const;
1289  ON_3dVector operator-(const ON_2fVector&) const;
1290  ON_3dPoint operator-(const ON_2fPoint&) const;
1291 
1292  ON_3dVector operator*(const ON_Xform&) const;
1293 
1294  bool operator==(const ON_3dVector&) const;
1295  bool operator!=(const ON_3dVector&) const;
1296 
1297  // dictionary order comparisons
1298  bool operator<=(const ON_3dVector&) const;
1299  bool operator>=(const ON_3dVector&) const;
1300  bool operator<(const ON_3dVector&) const;
1301  bool operator>(const ON_3dVector&) const;
1302 
1303  // index operators mimic double[3] behavior
1304  double& operator[](int);
1305  double operator[](int) const;
1306  double& operator[](unsigned int);
1307  double operator[](unsigned int) const;
1308 
1309  /*
1310  Returns:
1311  False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
1312  */
1313  bool IsValid() const;
1314 
1315  /*
1316  Returns:
1317  True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
1318  */
1319  bool IsUnset() const;
1320 
1321  // set 3d vector value
1322  void Set(double x,double y,double z);
1323 
1324  int MaximumCoordinateIndex() const;
1325  double MaximumCoordinate() const; // absolute value of maximum coordinate
1326 
1327  int MinimumCoordinateIndex() const;
1328  double MinimumCoordinate() const; // absolute value of minimum coordinate
1329 
1330  double LengthSquared() const;
1331  double Length() const;
1332 
1333  bool Decompose( // Computes a, b, c such that this vector = a*X + b*Y + c*Z
1334  // Returns false if unable to solve for a,b,c. This happens
1335  // when X,Y,Z is not really a basis.
1336  //
1337  // If X,Y,Z is known to be an orthonormal frame,
1338  // then a = V*X, b = V*Y, c = V*Z will compute
1339  // the same result more quickly.
1340  const ON_3dVector&, // X
1341  const ON_3dVector&, // Y
1342  const ON_3dVector&, // Z
1343  double*, // a
1344  double*, // b
1345  double* // c
1346  ) const;
1347 
1348  int IsParallelTo(
1349  // returns 1: this and other vectors are parallel
1350  // -1: this and other vectors are anti-parallel
1351  // 0: this and other vectors are not parallel
1352  // or at least one of the vectors is zero
1353  const ON_3dVector& other, // other vector
1354  double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
1355  ) const;
1356 
1357  bool IsPerpendicularTo(
1358  // returns true: this and other vectors are perpendicular
1359  // false: this and other vectors are not perpendicular
1360  // or at least one of the vectors is zero
1361  const ON_3dVector& other, // other vector
1362  double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
1363  ) const;
1364 
1365  double Fuzz( double tolerance = ON_ZERO_TOLERANCE ) const; // tolerance to use when comparing 3d vectors
1366 
1367 #if defined(OPENNURBS_WALL)
1368  // Goal is to eventually remove all functions that modify vectors in place.
1369  ON_DEPRECATED_MSG("Use v = ON_3dVector::ZeroVector;")
1370 #endif
1371  void Zero(); // set all coordinates to zero;
1372 
1373 #if defined(OPENNURBS_WALL)
1374  // Goal is to eventually remove all functions that modify vectors in place.
1375  ON_DEPRECATED_MSG("Use v = -v;")
1376 #endif
1377  void Reverse(); // negate all coordinates
1378 
1379  bool Unitize(); // returns false if vector has zero length
1380  double LengthAndUnitize(); // unitizes and returns initial length
1381 
1382  /*
1383  Returns:
1384  If this is a valid non-zero vector, a unit vector parallel to this is returned.
1385  Otherwise the zero vector is returned.
1386  */
1387  ON_3dVector UnitVector() const;
1388 
1389  // Description:
1390  // Test a vector to see if it is very short
1391  //
1392  // Parameters:
1393  // tiny_tol - [in] (default = ON_ZERO_TOLERANCE) a nonzero
1394  // value used as the coordinate zero tolerance.
1395  //
1396  // Returns:
1397  // ( fabs(x) <= tiny_tol && fabs(y) <= tiny_tol && fabs(z) <= tiny_tol )
1398  //
1399  bool IsTiny(
1400  double tiny_tol = ON_ZERO_TOLERANCE // tiny_tol
1401  ) const;
1402 
1403  // Returns:
1404  // true if vector is the zero vector.
1405  bool IsZero() const;
1406 
1407  /*
1408  Returns:
1409  true if at lease one coordinate is not zero and no coordinates are nans.
1410  */
1411  bool IsNotZero() const;
1412 
1413 
1414  // Returns:
1415  // true if vector is valid and has length 1.
1416  bool IsUnitVector() const;
1417 
1418  // set this vector to be perpendicular to another vector
1419  bool PerpendicularTo( // Result is not unitized.
1420  // returns false if input vector is zero
1421  const ON_3dVector&
1422  );
1423 
1424  // set this vector to be perpendicular to a plane defined by 3 points
1425  bool PerpendicularTo(
1426  // about 3 times slower than
1427  // ON_3dVector N = ON_CrossProduct(P1-P0,P2-P0);
1428  // N.Unitize();
1429  // returns false if points are coincident or collinear
1430  const ON_3dPoint&, const ON_3dPoint&, const ON_3dPoint&
1431  );
1432 
1433  // These transform the vector in place. The transformation matrix acts on
1434  // the left of the vector; i.e., result = transformation*vector
1435  void Transform(
1436  const ON_Xform& // can use ON_Xform here
1437  );
1438 
1439  void Rotate(
1440  double angle, // angle in radians
1441  const ON_3dVector& axis // axis of rotation
1442  );
1443 
1444  void Rotate(
1445  double sin_angle, // sin(angle)
1446  double cos_angle, // cos(angle)
1447  const ON_3dVector& axis // axis of rotation
1448  );
1449 
1450  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
1451 };
1452 
1453 class ON_CLASS ON_3dRay
1454 {
1455 public:
1456  ON_3dPoint m_P;
1457  ON_3dVector m_V;
1458 };
1459 
1460 /*
1461 Description:
1462  Typically the vector portion is a unit vector and
1463  m_d = -(x*P.x + y*P.y + z*P.z) for a point P on the plane.
1464 */
1465 class ON_CLASS ON_PlaneEquation
1466 {
1467 public:
1468  // C++ defaults for construction, destruction, copys, and operator=
1469  // work fine.
1470 
1471  static const ON_PlaneEquation UnsetPlaneEquation; // (ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE)
1472  static const ON_PlaneEquation ZeroPlaneEquation; // (0.0,0.0,0.0,0.0)
1473 
1474  ON_PlaneEquation();
1475 
1477  double xx, double yy, double zz, double dd
1478  );
1479 
1480  static void Set(
1481  ON_PlaneEquation& plane_equation,
1482  double x, double y, double z, double d
1483  );
1484 
1485  double MaximumCoefficient() const;
1486 
1487  /*
1488  Returns:
1489  The plane equation whose coefficient values are
1490  the negative of the coefficent values in this,
1491  provided the coeffient value is valid. Any invalid
1492  coefficent values are copied.
1493  */
1494  ON_PlaneEquation NegatedPlaneEquation() const;
1495 
1496 
1497  /*
1498  Returns:
1499  The plane equation whose first three coefficient values
1500  are a unit vector.
1501  */
1502  ON_PlaneEquation UnitizedPlaneEquation() const;
1503 
1504 
1505 
1506  /*
1507  Description:
1508  returns true if x, y, z, d are valid, finite doubles.
1509  Remarks:
1510  this function will return true if x, y and z are all zero.
1511  See Also:
1512  ON_PlaneEquation::IsSet().
1513  */
1514  bool IsValid() const;
1515 
1516  /*
1517  Description:
1518  returns true if x, y, z, d are valid, finite doubles and
1519  at least one of x, y or z is not zero.
1520  */
1521  bool IsSet() const;
1522 
1523  /*
1524  Description:
1525  Sets (x,y,z) to a unitized N and then sets
1526  d = -(x*P.x + y*P.y + z*P.z).
1527  Parameters:
1528  P - [in] point on the plane
1529  N - [in] vector perpendicular to the plane
1530  Returns:
1531  true if input is valid.
1532  */
1533  bool Create( ON_3dPoint P, ON_3dVector N );
1534 
1535  // index operators mimic double[4] behavior
1536  // Return null refs or ON_UNSET_VALUE for out-of-range indices
1537  double& operator[](int);
1538  double& operator[](unsigned int);
1539  double operator[](int) const;
1540  double operator[](unsigned int) const;
1541 
1542  /*
1543  Returns:
1544  Direction (x,y,z)
1545  */
1546  ON_3dVector Direction() const;
1547 
1548  double DirectionLength() const;
1549 
1550  /*
1551  Returns:
1552  Unitized direction or zero vector if not set.
1553  */
1554  ON_3dVector UnitNormal() const;
1555 
1556  /*
1557  Returns 1: this and other vectors are parallel
1558  -1: this and other vectors are anti-parallel
1559  0: this and other vectors are not parallel
1560  or at least one of the vectors is zero
1561  */
1562  int IsParallelTo(
1563  const ON_PlaneEquation& other, // other plane equation
1564  double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
1565  ) const;
1566 
1567  /*
1568  Description:
1569  Evaluate the plane at a point.
1570  Parameters:
1571  P - [in]
1572  Returns:
1573  x*P.x + y*P.y + z*P.z + d;
1574  */
1575  double ValueAt(ON_3dPoint P) const;
1576  double ValueAt(ON_4dPoint P) const;
1577  double ValueAt(ON_3dVector P) const;
1578  double ValueAt(double x, double y, double z) const;
1579 
1580  /*
1581  Returns:
1582  ON_Interval::EmptyInterval if input is not valid.
1583  */
1584  ON_Interval ValueRange(
1585  size_t point_list_count,
1586  const ON_3dPoint* point_list
1587  ) const;
1588 
1589  /*
1590  Returns:
1591  ON_Interval::EmptyInterval if input is not valid.
1592  */
1593  ON_Interval ValueRange(
1594  const ON_SimpleArray< ON_3dPoint >& point_list
1595  ) const;
1596 
1597  /*
1598  Returns:
1599  ON_Interval::EmptyInterval if input is not valid.
1600  */
1601  ON_Interval ValueRange(
1602  size_t point_list_count,
1603  const ON_3fPoint* point_list
1604  ) const;
1605 
1606  /*
1607  Returns:
1608  ON_Interval::EmptyInterval if input is not valid.
1609  */
1610  ON_Interval ValueRange(
1611  const ON_SimpleArray< ON_3fPoint >& point_list
1612  ) const;
1613 
1614  /*
1615  Returns:
1616  ON_Interval::EmptyInterval if input is not valid.
1617  */
1618  ON_Interval ValueRange(
1619  const class ON_3dPointListRef& point_list
1620  ) const;
1621 
1622  /*
1623  Returns:
1624  ON_Interval::EmptyInterval if input is not valid.
1625  */
1626  ON_Interval ValueRange(
1627  size_t point_index_count,
1628  const unsigned int* point_index_list,
1629  const class ON_3dPointListRef& point_list
1630  ) const;
1631 
1632  ON_Interval ValueRange(
1633  size_t point_index_count,
1634  size_t point_index_stride,
1635  const unsigned int* point_index_list,
1636  const class ON_3dPointListRef& point_list
1637  ) const;
1638 
1639  /*
1640  Description:
1641  Evaluate the plane at a list of point values.
1642  Parameters:
1643  Pcount - [in]
1644  number of points
1645  P - [in]
1646  points
1647  value - [in]
1648  If not null, value[] must be an array of length at least Pcount.
1649  The values will be stored in this array. If null, the an array
1650  will be allocated with onmalloc() and returned.
1651  value_range - [out]
1652  If not null, the range of values will be returned here.
1653  Returns:
1654  An array of Pcount values. If the input parameter value was null,
1655  then the array is allocated on the heap using onmalloc() and the
1656  caller is responsible for calling onfree() when finished. If the
1657  input is not valid, null is returned.
1658  */
1659  double* ValueAt(
1660  int Pcount,
1661  const ON_3fPoint* P,
1662  double* value,
1663  double value_range[2]
1664  ) const;
1665 
1666  double* ValueAt(
1667  int Pcount,
1668  const ON_3dPoint* P,
1669  double* value,
1670  double value_range[2]
1671  ) const;
1672 
1673  /*
1674  Description:
1675  This function calculates and evalutes points that
1676  would be exactly on the plane if double precision
1677  aritmetic were mathematically perfect and returns
1678  the largest value of the evaluations.
1679  */
1680  double ZeroTolerance() const;
1681 
1682  /*
1683  Description:
1684  Transform the plane equation so that, if e0 is the initial
1685  equation, e1 is transformed equation and P is a point,
1686  then e0.ValueAt(P) = e1.ValueAt(xform*P).
1687  Parameters:
1688  xform - [in]
1689  Invertable transformation.
1690  Returns:
1691  True if the plane equation was successfully transformed.
1692  False if xform is not invertable or the equation is not
1693  valid.
1694  Remarks:
1695  This function has to invert xform. If you have apply the
1696  same transformation to a bunch of planes, then it will be
1697  more efficient to calculate xform's inverse transpose
1698  and apply the resultingt transformation to the equation's
1699  coefficients as if they were 4d point coordinates.
1700  */
1701  bool Transform( const ON_Xform& xform );
1702 
1703  /*
1704  Description:
1705  Get point on plane that is closest to a given point.
1706  Parameters:
1707  point - [in]
1708  Returns:
1709  A 3d point on the plane that is closest to the input point.
1710  */
1711  ON_3dPoint ClosestPointTo( ON_3dPoint point ) const;
1712 
1713  /*
1714  Description:
1715  Get the minimum value of the plane equation
1716  on a bounding box.
1717  Parameters:
1718  bbox - [in]
1719  Returns:
1720  Minimum value of the plane equation on the bounding box.
1721  */
1722  double MinimumValueAt(const ON_BoundingBox& bbox) const;
1723 
1724  /*
1725  Description:
1726  Get the maximum value of the plane equation
1727  on a bounding box.
1728  Parameters:
1729  bbox - [in]
1730  Returns:
1731  Maximum value of the plane equation on the bounding box.
1732  */
1733  double MaximumValueAt(const ON_BoundingBox& bbox) const;
1734 
1735 
1736  /*
1737  Description:
1738  Get the maximum value of the plane equation on a set of 3d points.
1739  Parameters:
1740  bRational - [in]
1741  False if the points are euclidean (x,y,z)
1742  True if the points are homogenous rational (x,y,z,w)
1743  (x/w,y/w,z/w) is used to evaluate the value.
1744  point_count - [in]
1745  point_stride - [in]
1746  i-th point's x coordinate = points[i*point_stride]
1747  points - [in]
1748  coordinates of points
1749  stop_value - [in]
1750  If stop_value is valid and not ON_UNSET_VALUE, then the
1751  evaulation stops if a value > stop_value is found.
1752  If stop_value = ON_UNSET_VALUE, then stop_value is ignored.
1753  Returns:
1754  Maximum value of the plane equation on the point list.
1755  If the input is not valid, then ON_UNSET_VALUE is returned.
1756  */
1757  double MaximumValueAt(
1758  bool bRational,
1759  int point_count,
1760  int point_stride,
1761  const double* points,
1762  double stop_value
1763  ) const;
1764 
1765  /*
1766  Description:
1767  Get the minimum value of the plane equation on a set of 3d points.
1768  Parameters:
1769  bRational - [in]
1770  False if the points are euclidean (x,y,z)
1771  True if the points are homogenous rational (x,y,z,w)
1772  (x/w,y/w,z/w) is used to evaluate the value.
1773  point_count - [in]
1774  point_stride - [in]
1775  i-th point's x coordinate = points[i*point_stride]
1776  points - [in]
1777  coordinates of points
1778  stop_value - [in]
1779  If stop_value is valid and not ON_UNSET_VALUE, then the
1780  evaulation stops if a value < stop_value is found.
1781  If stop_value = ON_UNSET_VALUE, then stop_value is ignored.
1782  Returns:
1783  Maximum value of the plane equation on the point list.
1784  If the input is not valid, then ON_UNSET_VALUE is returned.
1785  */
1786  double MinimumValueAt(
1787  bool bRational,
1788  int point_count,
1789  int point_stride,
1790  const double* points,
1791  double stop_value
1792  ) const;
1793 
1794  /*
1795  Description:
1796  Get the maximum absolute value of the plane equation
1797  on a set of 3d points.
1798  Parameters:
1799  bRational - [in]
1800  False if the points are euclidean (x,y,z)
1801  True if the points are homogenous rational (x,y,z,w)
1802  (x/w,y/w,z/w) is used to evaluate the value.
1803  point_count - [in]
1804  point_stride - [in]
1805  i-th point's x coordinate = points[i*point_stride]
1806  points - [in]
1807  coordinates of points
1808  stop_value - [in]
1809  If stop_value >= 0.0, then the evaulation stops if an
1810  absolute value > stop_value is found. If stop_value < 0.0
1811  or stop_value is invalid, then stop_value is ignored.
1812  Returns:
1813  Maximum value of the plane equation on the point list.
1814  If the input is not valid, then ON_UNSET_VALUE is returned.
1815  */
1816  double MaximumAbsoluteValueAt(
1817  bool bRational,
1818  int point_count,
1819  int point_stride,
1820  const double* points,
1821  double stop_value
1822  ) const;
1823 
1824  /*
1825  Description:
1826  Test points on a bezier curve to see if they are near the plane.
1827  Parameters:
1828  bezcrv - [in]
1829  s0 - [in]
1830  s1 - [in] the interval from s0 to s1 is tested (s0 < s1)
1831  sample_count - [in] number of interior points to test.
1832  Numbers like 1, 3, 7, 15, ... work best.
1833  endpoint_tolerance - [in] If >= 0, then the end points are
1834  tested to see if the distance from the endpoints
1835  is <= endpoint_tolerance.
1836  interior_tolerance - [in] (>=0 and >=endpoint_tolerance)
1837  This tolerance is used to test the interior sample points.
1838  smin - [put] If not nullptr, *smin = bezier parameter of nearest
1839  test point.
1840  smax - [put] If not nullptr, *smax = bezier parameter of farthest
1841  test point. If false is returned, this is the
1842  parameter of the test point that failed.
1843  Returns:
1844  True if all the tested points passed the tolerance test.
1845  False if at least one tested point failed the tolerance test.
1846  (The test terminates when the first failure is encountered.)
1847  */
1848  bool IsNearerThan(
1849  const class ON_BezierCurve& bezcrv,
1850  double s0,
1851  double s1,
1852  int sample_count,
1853  double endpoint_tolerance,
1854  double interior_tolerance,
1855  double* smin,
1856  double* smax
1857  ) const;
1858 
1859  bool operator==(const ON_PlaneEquation&) const;
1860  bool operator!=(const ON_PlaneEquation&) const;
1861 
1862  double x;
1863  double y;
1864  double z;
1865  double d; // 4th coefficient of the plane equation.
1866 };
1867 
1868 #if defined(ON_DLL_TEMPLATE)
1869 
1870 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_PlaneEquation>;
1871 
1872 #endif
1873 
1874 ON_DECL
1875 ON_3dVector operator*(int, const ON_3dVector&);
1876 
1877 ON_DECL
1878 ON_3dVector operator*(float, const ON_3dVector&);
1879 
1880 ON_DECL
1881 ON_3dVector operator*(double, const ON_3dVector&);
1882 
1883 ///////////////////////////////////////////////////////////////
1884 //
1885 // ON_3dVector utilities
1886 //
1887 
1888 ON_DECL
1889 double
1890 ON_DotProduct(
1891  const ON_3dVector&,
1892  const ON_3dVector&
1893  );
1894 
1895 
1896 ON_DECL
1897 ON_3dVector
1898 ON_CrossProduct(
1899  const ON_3dVector&,
1900  const ON_3dVector&
1901  );
1902 
1903 ON_DECL
1904 ON_3dVector
1905 ON_CrossProduct( // 3d cross product for old fashioned arrays
1906  const double*, // array of 3d doubles
1907  const double* // array of 3d doubles
1908  );
1909 
1910 ON_DECL
1911 double
1912 ON_TripleProduct(
1913  const ON_3dVector&,
1914  const ON_3dVector&,
1915  const ON_3dVector&
1916  );
1917 
1918 ON_DECL
1919 double
1920 ON_TripleProduct( // 3d triple product for old fashioned arrays
1921  const double*, // array of 3d doubles
1922  const double*, // array of 3d doubles
1923  const double* // array of 3d doubles
1924  );
1925 
1926 ON_DECL
1927 bool
1928 ON_IsOrthogonalFrame( // true if X, Y, Z are nonzero and mutually perpendicular
1929  const ON_3dVector&, // X
1930  const ON_3dVector&, // Y
1931  const ON_3dVector& // Z
1932  );
1934 ON_DECL
1935 bool
1936 ON_IsOrthonormalFrame( // true if X, Y, Z are orthogonal and unit length
1937  const ON_3dVector&, // X
1938  const ON_3dVector&, // Y
1939  const ON_3dVector& // Z
1940  );
1941 
1942 ON_DECL
1943 bool
1944 ON_IsRightHandFrame( // true if X, Y, Z are orthonormal and right handed
1945  const ON_3dVector&, // X
1946  const ON_3dVector&, // Y
1947  const ON_3dVector& // Z
1948  );
1949 
1950 ///////////////////////////////////////////////////////////////
1951 //
1952 // common points and vectors
1953 //
1954 // ON_unset_point is obsolete - use ON_3dPoint::UnsetPoint
1955 #if !defined(OPENNURBS_WALL)
1956 
1957 // OBSOLETE - use ON_3dPoint::UnsetPoint
1958 #define ON_unset_point ON_3dPoint::UnsetPoint
1959 // OBSOLETE - use ON_3dPoint::UnsetPoint
1960 #define ON_UNSET_POINT ON_3dPoint::UnsetPoint
1961 // OBSOLETE - use ON_3dPoint::UnsetVector
1962 #define ON_UNSET_VECTOR ON_3dVector::UnsetVector
1963 // OBSOLETE - use ON_3dPoint::Origin
1964 #define ON_origin ON_3dPoint::Origin
1965 // OBSOLETE - use ON_3dVector::XAxis
1966 #define ON_xaxis ON_3dVector::XAxis
1967 // OBSOLETE - use ON_3dVector::YAxis
1968 #define ON_yaxis ON_3dVector::YAxis
1969 // OBSOLETE - use ON_3dVector::ZAxis
1970 #define ON_zaxis ON_3dVector::ZAxis
1971 // OBSOLETE - use ON_3fPoint::Origin
1972 #define ON_forigin ON_3fPoint::Origin
1973 // OBSOLETE - use ON_3fVector::XAxis
1974 #define ON_fxaxis ON_3fVector::XAxis
1975 // OBSOLETE - use ON_3fVector::YAxis
1976 #define ON_fyaxis ON_3fVector::YAxis
1977 // OBSOLETE - use ON_3fVector::ZAxis
1978 #define ON_fzaxis ON_3fVector::ZAxis
1979 
1980 #endif
1981 
1982 #include "opennurbs_fpoint.h"
1983 
1984 ////////////////////////////////////////////////////////////////
1985 //
1986 // ON_SurfaceCurvature
1987 //
1988 class ON_CLASS ON_SurfaceCurvature
1989 {
1990 public:
1991  double k1, k2; // principal curvatures
1992 
1993  double GaussianCurvature() const;
1994  double MeanCurvature() const;
1995  double MinimumRadius() const;
1996  double MaximumRadius() const;
1997 };
1998 
1999 
2000 #if defined(ON_DLL_TEMPLATE)
2001 
2002 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dPoint>;
2003 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3dPoint>;
2004 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_4dPoint>;
2005 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dVector>;
2006 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3dVector>;
2007 
2008 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2fPoint>;
2009 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3fPoint>;
2010 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_4fPoint>;
2011 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2fVector>;
2012 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3fVector>;
2013 
2014 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Color>;
2015 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_SurfaceCurvature>;
2016 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Interval>;
2017 
2018 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dex>;
2019 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3dex>;
2020 
2021 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_COMPONENT_INDEX>;
2022 
2023 #endif
2024 
2025 /////////////////////////////////////////////////////////////////
2026 //
2027 
2028 class ON_CLASS ON_2dPointArray : public ON_SimpleArray<ON_2dPoint>
2029 {
2030 public:
2031  // see ON_SimpleArray class definition comments for constructor documentation
2032  ON_2dPointArray();
2033  ON_2dPointArray(int);
2034  ON_2dPointArray( const ON_2dPointArray& );
2035  ON_2dPointArray& operator=( const ON_2dPointArray& );
2036 
2037  bool GetBBox( // returns true if successful
2038  double boxmin[2],
2039  double boxmax[2],
2040  bool bGrowBox = false // true means grow box
2041  ) const;
2042 
2043  bool Transform( const ON_Xform& );
2044  bool SwapCoordinates(int,int);
2045 };
2046 
2047 
2048 /////////////////////////////////////////////////////////////////
2049 //
2050 
2051 class ON_CLASS ON_2fPointArray : public ON_SimpleArray<ON_2fPoint>
2052 {
2053 public:
2054  // see ON_SimpleArray class definition comments for constructor documentation
2055  ON_2fPointArray();
2056  ON_2fPointArray(int);
2058  ON_2fPointArray& operator=( const ON_2fPointArray& );
2059 
2060  bool GetBBox( // returns true if successful
2061  float boxmin[2],
2062  float boxmax[2],
2063  bool bGrowBox = false // true means grow box
2064  ) const;
2065  bool Transform( const ON_Xform& );
2066  bool SwapCoordinates(int,int);
2067 };
2068 
2069 
2070 /////////////////////////////////////////////////////////////////
2071 //
2072 
2073 class ON_CLASS ON_3dPointArray : public ON_SimpleArray<ON_3dPoint>
2074 {
2075 public:
2076  // see ON_SimpleArray class definition comments for constructor documentation
2077  ON_3dPointArray();
2078  ON_3dPointArray(int);
2080  ON_3dPointArray& operator=( const ON_3dPointArray& );
2082  ON_3dPointArray& operator=( const ON_SimpleArray<ON_3fPoint>& );
2083 
2084  // Description:
2085  // Create 3d point list
2086  // Parameters:
2087  // point_dimension - [in] dimension of input points (2 or 3)
2088  // bRational - [in] true if points are in homogenous rational form
2089  // point_count - [in] number of points
2090  // point_stride - [in] number of doubles to skip between points
2091  // points - [in] array of point coordinates
2092  bool Create(
2093  int point_dimension,
2094  int bRational,
2095  int point_count,
2096  int point_stride,
2097  const double* points
2098  );
2099 
2100  // Description:
2101  // Create 3d point list
2102  // Parameters:
2103  // point_dimension - [in] dimension of input points (2 or 3)
2104  // bRational - [in] true if points are in homogenous rational form
2105  // point_count - [in] number of points
2106  // point_stride - [in] number of doubles to skip between points
2107  // points - [in] array of point coordinates
2108  bool Create(
2109  int point_dimension,
2110  int bRational,
2111  int point_count,
2112  int point_stride,
2113  const float* points
2114  );
2115 
2116  // Description:
2117  // Get 3d axis aligned bounding box.
2118  // Returns:
2119  // 3d bounding box of point list.
2120  ON_BoundingBox BoundingBox() const;
2121 
2122  // Description:
2123  // Get 3d axis aligned bounding box or the union
2124  // of the input box with the point list's bounding box.
2125  // Parameters:
2126  // bbox - [in/out] 3d axis aligned bounding box
2127  // bGrowBox - [in] (default=false)
2128  // If true, then the union of the input bbox and the
2129  // point list's bounding box is returned in bbox.
2130  // If false, the point list's bounding box is returned in bbox.
2131  // Returns:
2132  // true if successful.
2133  bool GetBoundingBox(
2134  ON_BoundingBox& bbox,
2135  int bGrowBox = false
2136  ) const;
2137 
2138  // Description:
2139  // Get axis aligned bounding box.
2140  // Parameters:
2141  // boxmin - [in/out] array of 3 doubles
2142  // boxmax - [in/out] array of 3 doubles
2143  // bGrowBox - [in] (default=false)
2144  // If true, then the union of the input bounding box and the
2145  // object's bounding box is returned.
2146  // If false, the object's bounding box is returned.
2147  // Returns:
2148  // true if object has bounding box and calculation was successful
2149  bool GetBBox(
2150  double boxmin[3],
2151  double boxmax[3],
2152  bool bGrowBox = false
2153  ) const;
2154 
2155  /*
2156  Description:
2157  Get tight bounding box of the point list.
2158  Parameters:
2159  tight_bbox - [in/out] tight bounding box
2160  bGrowBox -[in] (default=false)
2161  If true and the input tight_bbox is valid, then returned
2162  tight_bbox is the union of the input tight_bbox and the
2163  tight bounding box of the point list.
2164  xform -[in] (default=nullptr)
2165  If not nullptr, the tight bounding box of the transformed
2166  point list is calculated. The point list is not modified.
2167  Returns:
2168  True if the returned tight_bbox is set to a valid
2169  bounding box.
2170  */
2171  bool GetTightBoundingBox(
2172  ON_BoundingBox& tight_bbox,
2173  bool bGrowBox = false,
2174  const ON_Xform* xform = nullptr
2175  ) const;
2176 
2177  // Description:
2178  // Transform points by applying xform to each point.
2179  // Parameters:
2180  // xform - [in] transformation matrix
2181  // Returns:
2182  // true if successful.
2183  bool Transform(
2184  const ON_Xform& xform
2185  );
2186 
2187  // Description:
2188  // Swaps point coordinate values with indices i and j.
2189  // Parameters:
2190  // i - [in] coordinate index
2191  // j - [in] coordinate index
2192  // Returns:
2193  // true if successful.
2194  // Example:
2195  // The call SwapCoordinates(0,2) would swap the x and z
2196  // coordinates of each point in the array.
2197  bool SwapCoordinates(
2198  int i,
2199  int j
2200  );
2201 
2202  // Description:
2203  // Rotate points about a center and axis. A positive angle
2204  // results in a counter-clockwise rotation about the axis
2205  // of rotation.
2206  // Parameters:
2207  // sin_angle - [in] sine of rotation angle
2208  // cos_angle - [in] cosine of rotation angle
2209  // axis_of_rotation - [in] axis of rotation
2210  // center_of_rotation - [in] center (fixed point) of rotation
2211  // Returns:
2212  // true if successful.
2213  bool Rotate(
2214  double sin_angle,
2215  double cos_angle,
2216  const ON_3dVector& axis_of_rotation,
2217  const ON_3dPoint& center_of_rotation
2218  );
2219 
2220  // Description:
2221  // Rotate points about a center and axis. A positive angle
2222  // results in a counter-clockwise rotation about the axis
2223  // of rotation.
2224  // Parameters:
2225  // angle - [in] angle in radians. Polsine of rotation angle
2226  // cos_angle - [in] cosine of rotation angle
2227  // axis_of_rotation - [in] axis of rotation
2228  // center_of_rotation - [in] center (fixed point) of rotation
2229  // Returns:
2230  // true if successful.
2231  bool Rotate(
2232  double angle_in_radians,
2233  const ON_3dVector& axis_of_rotation,
2234  const ON_3dPoint& center_of_rotation
2235  );
2236 
2237  // Description:
2238  // Translate a polyline
2239  // Parameters:
2240  // delta - [in] translation vectorsine of rotation angle
2241  // Returns:
2242  // true if successful.
2243  bool Translate(
2244  const ON_3dVector& delta
2245  );
2246 
2247  /*
2248  Description:
2249  Get the index of the point in the array that is closest
2250  to P.
2251  Parameters:
2252  P - [in]
2253  closest_point_index - [out]
2254  maximum_distance - [in] optional distance constraint.
2255  If maximum_distance > 0, then only points Q with
2256  |P-Q| <= maximum_distance are returned.
2257  Returns:
2258  True if a point is found; in which case *closest_point_index
2259  is the index of the point. False if no point is found
2260  or the input is not valid.
2261  See Also:
2262  ON_GetClosestPointInPointList
2263  ON_PointCloud::GetClosestPoint
2264  */
2265  bool GetClosestPoint(
2266  ON_3dPoint P,
2267  int* closest_point_index,
2268  double maximum_distance = 0.0
2269  ) const;
2270 
2271 };
2273 
2274 /////////////////////////////////////////////////////////////////
2275 //
2276 
2277 class ON_CLASS ON_3fPointArray : public ON_SimpleArray<ON_3fPoint>
2278 {
2279 public:
2280  // see ON_SimpleArray class definition comments for constructor documentation
2281  ON_3fPointArray();
2282  ON_3fPointArray(int);
2284  ON_3fPointArray& operator=( const ON_3fPointArray& );
2285 
2286  bool GetBBox(
2287  float boxmin[3],
2288  float boxmax[3],
2289  bool bGrowBox = false
2290  ) const;
2291 
2292  bool Transform( const ON_Xform& );
2293 
2294  bool SwapCoordinates(int,int);
2295 };
2296 
2297 
2298 /////////////////////////////////////////////////////////////////
2299 //
2300 
2301 class ON_CLASS ON_4dPointArray : public ON_SimpleArray<ON_4dPoint>
2302 {
2303 public:
2304  // see ON_SimpleArray class definition comments for constructor documentation
2305  ON_4dPointArray();
2306  ON_4dPointArray(int);
2308  ON_4dPointArray& operator=( const ON_4dPointArray& );
2309 
2310  bool Transform( const ON_Xform& );
2311  bool SwapCoordinates(int,int);
2312 };
2313 
2314 
2315 /////////////////////////////////////////////////////////////////
2316 //
2317 
2318 class ON_CLASS ON_4fPointArray : public ON_SimpleArray<ON_4fPoint>
2319 {
2320 public:
2321  // see ON_SimpleArray class definition comments for constructor documentation
2322  ON_4fPointArray();
2323  ON_4fPointArray(int);
2325  ON_4fPointArray& operator=( const ON_4fPointArray& );
2326 
2327  bool Transform( const ON_Xform& );
2328  bool SwapCoordinates(int,int);
2329 };
2330 
2331 
2332 /////////////////////////////////////////////////////////////////
2333 //
2334 
2336 {
2337 public:
2338  // see ON_SimpleArray class definition comments for constructor documentation
2339  ON_2dVectorArray();
2340  ON_2dVectorArray(int);
2342  ON_2dVectorArray& operator=( const ON_2dVectorArray& );
2343 
2344  bool GetBBox(
2345  double boxmin[2],
2346  double boxmax[2],
2347  bool bGrowBox = false
2348  ) const;
2349 
2350  bool Transform( const ON_Xform& );
2351  bool SwapCoordinates(int,int);
2352 };
2353 
2354 
2355 /////////////////////////////////////////////////////////////////
2356 //
2357 
2358 class ON_CLASS ON_2fVectorArray : public ON_SimpleArray<ON_2fVector>
2359 {
2360 public:
2361  // see ON_SimpleArray class definition comments for constructor documentation
2362  ON_2fVectorArray();
2363  ON_2fVectorArray(int);
2365  ON_2fVectorArray& operator=( const ON_2fVectorArray& );
2366 
2367  bool GetBBox(
2368  float boxmin[2],
2369  float boxmax[2],
2370  bool = false
2371  ) const;
2372 
2373  bool Transform( const ON_Xform& );
2374  bool SwapCoordinates(int,int);
2375 };
2376 
2377 
2378 /////////////////////////////////////////////////////////////////
2379 //
2380 
2381 class ON_CLASS ON_3dVectorArray : public ON_SimpleArray<ON_3dVector>
2382 {
2383 public:
2384  ON_3dVectorArray();
2385  ON_3dVectorArray(int);
2387  ON_3dVectorArray& operator=( const ON_3dVectorArray& );
2388 
2389  bool GetBBox(
2390  double boxmin[3],
2391  double boxmax[3],
2392  bool bGrowBow = false
2393  ) const;
2394 
2395  bool Transform( const ON_Xform& );
2396  bool SwapCoordinates(int,int);
2397 };
2398 
2399 /////////////////////////////////////////////////////////////////
2400 //
2401 
2402 class ON_CLASS ON_3fVectorArray : public ON_SimpleArray<ON_3fVector>
2403 {
2404 public:
2405  ON_3fVectorArray();
2406  ON_3fVectorArray(int);
2408  ON_3fVectorArray& operator=( const ON_3fVectorArray& );
2409 
2410  bool GetBBox(
2411  float boxmin[3],
2412  float boxmax[3],
2413  bool bGrowBox = false
2414  ) const;
2415 
2416  bool Transform( const ON_Xform& );
2417  bool SwapCoordinates(int,int);
2418 };
2419 
2420 class ON_CLASS ON_3dPointListRef
2421 {
2422 public:
2423 
2424 
2426  : m_point_count(0)
2427  , m_point_stride(0)
2428  , m_dP(0)
2429  , m_fP(0)
2430  {}
2431 
2432  /*
2433  Description:
2434  Construct a point list that references the mesh vertex list.
2435  Remarks:
2436  If the mesh has double precision vertices, then the point
2437  list will refer to them; otherwise, the point list will
2438  refer to the single precision vertices.
2439  */
2441  const class ON_Mesh* mesh
2442  );
2443 
2444  /*
2445  Description:
2446  Construct a point list that references the points
2447  in a simple array of ON_3dPoint objects.
2448  */
2450  const class ON_SimpleArray<ON_3dPoint>& point_array
2451  );
2452 
2453  /*
2454  Description:
2455  Construct a point list that references the points
2456  in a simple array of ON_3fPoint objects.
2457  */
2459  const class ON_SimpleArray<ON_3fPoint>& point_array
2460  );
2461 
2462  static const ON_3dPointListRef EmptyPointList;
2463 
2464  static
2465  ON_3dPointListRef FromDoubleArray(
2466  size_t point_count,
2467  size_t point_stride,
2468  const double* point_array
2469  );
2470 
2471  static
2472  ON_3dPointListRef FromFloatArray(
2473  size_t point_count,
2474  size_t point_stride,
2475  const float* point_array
2476  );
2477 
2478  static
2479  ON_3dPointListRef FromPointArray(
2480  const class ON_SimpleArray<ON_3dPoint>& point_array
2481  );
2482 
2483  static
2484  ON_3dPointListRef FromPointArray(
2485  const class ON_SimpleArray<ON_3fPoint>& point_array
2486  );
2487 
2488  static
2489  ON_3dPointListRef FromMesh(
2490  const class ON_Mesh* mesh
2491  );
2492 
2493  /*
2494  Returns:
2495  A copy of the refenced points in an ON_SimpleArray<ON_3dPoint>.
2496  */
2497  ON_SimpleArray<ON_3dPoint> To3dPointArray() const;
2498 
2499  /*
2500  Returns:
2501  A copy of the refenced points in an ON_SimpleArray<ON_3fPoint>.
2502  */
2503  ON_SimpleArray<ON_3fPoint> To3fPointArray() const;
2504 
2505  /*
2506  Description:
2507  Set this point list to reference points with double coordinates.
2508  Parameters:
2509  point_count - [in]
2510  number of points
2511  point_stride - [in] (>= 3)
2512  number of doubles between points.
2513  point_array - [in]
2514  pointer to the first coordinate of the first point.
2515  Returns:
2516  Number of points in the list.
2517  */
2518  unsigned int SetFromDoubleArray(
2519  size_t point_count,
2520  size_t point_stride,
2521  const double* point_array
2522  );
2523 
2524  /*
2525  Description:
2526  Set this point list to reference points with float coordinates.
2527  Parameters:
2528  point_count - [in]
2529  number of points
2530  point_stride - [in] (>= 3)
2531  number of floats between points.
2532  point_array - [in]
2533  pointer to the first coordinate of the first point.
2534  Returns:
2535  Number of points in the list.
2536  */
2537  unsigned int SetFromFloatArray(
2538  size_t point_count,
2539  size_t point_stride,
2540  const float* point_array
2541  );
2542 
2543  /*
2544  Description:
2545  Set this point list to reference a mesh vertex list.
2546  Parameters:
2547  mesh - [in]
2548  Returns:
2549  Number of points in the list.
2550  */
2551  unsigned int SetFromMesh(
2552  const class ON_Mesh* mesh
2553  );
2554 
2555  /*
2556  Returns:
2557  0: no points
2558  1: single precison points (float coordinates)
2559  2: double precison points (double coordinates)
2560  */
2561  unsigned int Precision() const;
2562 
2563  /*
2564  Returns:
2565  true if the points are double precision
2566  */
2567  bool DoublePrecision() const;
2568 
2569  /*
2570  Returns:
2571  true if the points are single precision
2572  */
2573  bool SinglePrecision() const;
2574 
2575  /*
2576  Description:
2577  Copy point location into buffer and return it as an ON_3dPoint.
2578  Parameters:
2579  point_index - [in]
2580  buffer - [out]
2581  If point_index is a valid index, the point coordinates
2582  are copied to buffer[]; oherwise the buffer coordinates
2583  are set to ON_UNSET_VALUE.
2584  You must insure buffer is not null, has proper alignment
2585  for storing doubles, and is large enough to store three
2586  doubles.
2587  Returns:
2588  A reference to an ON_3dPoint which is a cast of buffer.
2589  Remarks:
2590  This is the fastest and most efficient way to get a the
2591  location of a point into memory you are managing.
2592  */
2593  inline const class ON_3dPoint& GetPoint(
2594  unsigned int point_index,
2595  double buffer[3]
2596  ) const
2597  {
2598  if ( point_index < m_point_count )
2599  {
2600  if ( m_dP )
2601  {
2602  const double* p = m_dP + (point_index*m_point_stride);
2603  buffer[0] = *p++;
2604  buffer[1] = *p++;
2605  buffer[2] = *p;
2606  }
2607  else
2608  {
2609  const float* p = m_fP + (point_index*m_point_stride);
2610  buffer[0] = *p++;
2611  buffer[1] = *p++;
2612  buffer[2] = *p;
2613  }
2614  }
2615  else
2616  {
2617  buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
2618  }
2619  return *((const ON_3dPoint*)buffer);
2620  }
2621 
2622  /*
2623  Parameters:
2624  point_index - [in]
2625  Returns:
2626  If point_index is a valid index, the point location is returned.
2627  Otherwise ON_3dPoint::UnsetPoint is returned.
2628  */
2629  inline ON_3dPoint Point(
2630  unsigned int point_index
2631  ) const
2632  {
2633  double buffer[3];
2634  if ( point_index < m_point_count )
2635  {
2636  if ( m_dP )
2637  {
2638  const double* p = m_dP + (point_index*m_point_stride);
2639  buffer[0] = *p++;
2640  buffer[1] = *p++;
2641  buffer[2] = *p;
2642  }
2643  else
2644  {
2645  const float* p = m_fP + (point_index*m_point_stride);
2646  buffer[0] = *p++;
2647  buffer[1] = *p++;
2648  buffer[2] = *p;
2649  }
2650  }
2651  else
2652  {
2653  buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
2654  }
2655  return *((const ON_3dPoint*)buffer);
2656  }
2657 
2658  inline ON_3dPoint operator[](int point_index) const
2659  {
2660  double buffer[3];
2661  if ( point_index >= 0 && ((unsigned int)point_index) < m_point_count )
2662  {
2663  if ( m_dP )
2664  {
2665  const double* p = m_dP + (point_index*m_point_stride);
2666  buffer[0] = *p++;
2667  buffer[1] = *p++;
2668  buffer[2] = *p;
2669  }
2670  else
2671  {
2672  const float* p = m_fP + (point_index*m_point_stride);
2673  buffer[0] = *p++;
2674  buffer[1] = *p++;
2675  buffer[2] = *p;
2676  }
2677  }
2678  else
2679  {
2680  buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
2681  }
2682  return *((const ON_3dPoint*)buffer);
2683  }
2684 
2685  inline ON_3dPoint operator[](unsigned int point_index) const
2686  {
2687  double buffer[3];
2688  if ( point_index < m_point_count )
2689  {
2690  if ( m_dP )
2691  {
2692  const double* p = m_dP + (point_index*m_point_stride);
2693  buffer[0] = *p++;
2694  buffer[1] = *p++;
2695  buffer[2] = *p;
2696  }
2697  else
2698  {
2699  const float* p = m_fP + (point_index*m_point_stride);
2700  buffer[0] = *p++;
2701  buffer[1] = *p++;
2702  buffer[2] = *p;
2703  }
2704  }
2705  else
2706  {
2707  buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
2708  }
2709  return *((const ON_3dPoint*)buffer);
2710  }
2711 
2712  inline ON_3dPoint operator[](ON__INT64 point_index) const
2713  {
2714  double buffer[3];
2715  if ( point_index >= 0 && ((ON__UINT64)point_index) < m_point_count )
2716  {
2717  if ( m_dP )
2718  {
2719  const double* p = m_dP + (point_index*m_point_stride);
2720  buffer[0] = *p++;
2721  buffer[1] = *p++;
2722  buffer[2] = *p;
2723  }
2724  else
2725  {
2726  const float* p = m_fP + (point_index*m_point_stride);
2727  buffer[0] = *p++;
2728  buffer[1] = *p++;
2729  buffer[2] = *p;
2730  }
2731  }
2732  else
2733  {
2734  buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
2735  }
2736  return *((const ON_3dPoint*)buffer);
2737  }
2738 
2739  inline ON_3dPoint operator[](ON__UINT64 point_index) const
2740  {
2741  double buffer[3];
2742  if ( point_index < m_point_count )
2743  {
2744  if ( m_dP )
2745  {
2746  const double* p = m_dP + (point_index*m_point_stride);
2747  buffer[0] = *p++;
2748  buffer[1] = *p++;
2749  buffer[2] = *p;
2750  }
2751  else
2752  {
2753  const float* p = m_fP + (point_index*m_point_stride);
2754  buffer[0] = *p++;
2755  buffer[1] = *p++;
2756  buffer[2] = *p;
2757  }
2758  }
2759  else
2760  {
2761  buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
2762  }
2763  return *((const ON_3dPoint*)buffer);
2764  }
2765 
2766  inline unsigned int PointCount() const
2767  {
2768  return m_point_count;
2769  }
2770 
2771  inline unsigned int PointStride() const
2772  {
2773  return m_point_stride;
2774  }
2775 
2776  inline const double* PointDoubleArray() const
2777  {
2778  return m_dP;
2779  }
2780 
2781  inline const float* PointFloatArray() const
2782  {
2783  return m_fP;
2784  }
2785 
2786  /*
2787  Returns:
2788  Number of points copied to face_points[] array.
2789  */
2790  unsigned int GetMeshFacePoints(
2791  const class ON_MeshFace* mesh_face,
2792  ON_3dPoint face_points[4]
2793  ) const;
2794 
2795  /*
2796  Returns:
2797  Number of points copied to ngon_points[] array.
2798  */
2799  unsigned int GetMeshNgonPoints(
2800  const class ON_MeshNgon* mesh_ngon,
2801  size_t ngon_points_capacity,
2802  class ON_3dPoint* ngon_points
2803  ) const;
2804 
2805  /*
2806  Returns:
2807  Number of points copied to ngon_points[] array.
2808  */
2809  unsigned int GetMeshNgonPoints(
2810  const class ON_MeshNgon* mesh_ngon,
2811  ON_SimpleArray<ON_3dPoint>& ngon_points
2812  ) const;
2813 
2814  /*
2815  Returns:
2816  Number of points copied to quad_points[] array.
2817  */
2818  unsigned int GetQuadPoints(
2819  const int quad_point_indices[4],
2820  class ON_3dPoint quad_points[4]
2821  ) const;
2822 
2823  /*
2824  Returns:
2825  Number of points copied to quad_points[] array.
2826  */
2827  unsigned int GetQuadPoints(
2828  const unsigned int quad_point_indices[4],
2829  class ON_3dPoint quad_points[4]
2830  ) const;
2831 
2832  /*
2833  Returns:
2834  Number of points copied to triangle_points[] array.
2835  */
2836  unsigned int GetTrianglePoints(
2837  const int triangle_point_indices[3],
2838  class ON_3dPoint triangle_points[3]
2839  ) const;
2840 
2841  /*
2842  Returns:
2843  Number of points copied to triangle_points[] array.
2844  */
2845  unsigned int GetTrianglePoints(
2846  const unsigned int triangle_point_indices[3],
2847  class ON_3dPoint triangle_points[3]
2848  ) const;
2849 
2850  /*
2851  Returns:
2852  Number of points copied to points[] array.
2853  */
2854  unsigned int GetPoints(
2855  int point_index_count,
2856  const int* point_index_list,
2857  class ON_3dPoint* points
2858  ) const;
2859 
2860  /*
2861  Returns:
2862  Number of points copied to points[] array.
2863  */
2864  unsigned int GetPoints(
2865  unsigned int point_index_count,
2866  const unsigned int* point_index_list,
2867  class ON_3dPoint* points
2868  ) const;
2869 
2870  /*
2871  Returns:
2872  Number of points copied to points[] array.
2873  */
2874  unsigned int GetPoints(
2875  const ON_SimpleArray<int>& point_index_list,
2877  ) const;
2878 
2879  /*
2880  Returns:
2881  Number of points copied to points[] array.
2882  */
2883  unsigned int GetPoints(
2884  int point_index_count,
2885  const int* point_index_list,
2887  ) const;
2888 
2889  /*
2890  Returns:
2891  Number of points copied to points[] array.
2892  */
2893  unsigned int GetPoints(
2894  unsigned int point_index_count,
2895  const unsigned int* point_index_list,
2897  ) const;
2898 
2899 private:
2900  unsigned int m_point_count;
2901  unsigned int m_point_stride;
2902  const double* m_dP;
2903  const float* m_fP;
2904 };
2906 
2907 
2908 
2909 
2910 
2911 
2912 
2913 /*
2914 Class ON_2dSize
2915 */
2916 class ON_CLASS ON_2dSize
2917 {
2918 public:
2919  // Default construction intentionally leaves x and y uninitialized.
2920  // Use something like
2921  // ON_2dSize pt(1.0,2.0);
2922  // or
2923  // ON_2dSize pt = ON_2dSize::Zero;
2924  // when you need an initialized ON_2dSize.
2925  ON_2dSize() = default;
2926 
2927  ~ON_2dSize() = default;
2928  ON_2dSize(const ON_2dSize& ) = default;
2929  ON_2dSize& operator=(const ON_2dSize& ) = default;
2930 
2931  ON_2dSize(
2932  double cx,
2933  double cy
2934  );
2935 
2936  /*
2937  Dictionary compare.
2938  Returns:
2939  -1: lhs < rhs
2940  0: lsh == rsh
2941  +1: lhs > rhs
2942  */
2943  static int Compare(
2944  const ON_2dSize& lhs,
2945  const ON_2dSize& rhs
2946  );
2947 
2948  /*
2949  Dictionary compare.
2950  Returns:
2951  -1: lhs < rhs
2952  0: lsh == rsh
2953  +1: lhs > rhs
2954  */
2955  static int ComparePointer(
2956  const ON_2dSize* lhs,
2957  const ON_2dSize* rhs
2958  );
2960 public:
2961  static const ON_2dSize Zero; // (0.0,0.0)
2962  static const ON_2dSize Unset; // (ON_UNSET_DOUBLE,ON_UNSET_DOUBLE)
2963 
2964 public:
2965  /*
2966  Returns:
2967  true if both cx and cy are 0.0
2968  */
2969  bool IsZero() const;
2970 
2971  /*
2972  Returns:
2973  true if neither cx nor cy are ON_UNSET_DOUBLE.
2974  */
2975  bool IsSet() const;
2976 
2977 public:
2978  double cx;
2979  double cy;
2980 };
2981 
2982 ON_DECL
2983 bool operator==(
2984  const ON_2dSize& lhs,
2985  const ON_2dSize& rhs
2986  );
2987 
2988 ON_DECL
2989 bool operator!=(
2990  const ON_2dSize& lhs,
2991  const ON_2dSize& rhs
2992  );
2993 
2994 #if defined(ON_DLL_TEMPLATE)
2995 
2996 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dSize>;
2997 
2998 #endif
2999 
3000 /*
3001 Class ON_4iRect
3002  For those situations where a Windows SDK RECT or MFC CRect
3003  value needs to be used in code that does not link with MFC.
3004  If you want a traditional bounding box, use ON_2dBoundingBox.
3005 */
3006 class ON_CLASS ON_4dRect
3007 {
3008 public:
3009  // Default construction intentionally leaves x and y uninitialized.
3010  // Use something like
3011  // ON_4dRect pt(1.0,2.0,3.0,4.0);
3012  // or
3013  // ON_4dRect pt = ON_4dRect::Zero;
3014  // when you need an initialized ON_4dRect.
3015  ON_4dRect() = default;
3016 
3017  ~ON_4dRect() = default;
3018  ON_4dRect(const ON_4dRect& ) = default;
3019  ON_4dRect& operator=(const ON_4dRect& ) = default;
3020 
3021  ON_4dRect(
3022  double left,
3023  double top,
3024  double right,
3025  double bottom
3026  );
3027 
3028  ON_4dRect(const ON_2dPoint topLeft, const ON_2dPoint& bottomRight);
3029  ON_4dRect(const ON_2dPoint& point, const ON_2dSize& size);
3030 
3031 public:
3032  static const ON_4dRect Zero; // (0.0,0.0,0.0,0.0)
3033  static const ON_4dRect Unset; // (ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX)
3034 
3035 public:
3036  /*
3037  Returns:
3038  true if all of left, top, right, and bottom are set to 0.
3039  */
3040  bool IsZero() const;
3041 
3042  void SetZero();
3043 
3044  /*
3045  Returns:
3046  true if none of left, top, right, or bottom is set to ON_UNSET_INT_INDEX
3047  */
3048  bool IsSet() const;
3049 
3050  double Width(void) const;
3051  double Height(void) const;
3052 
3053  const ON_2dSize Size(void) const;
3054 
3055  const ON_2dPoint CenterPoint(void) const;
3056  const ON_2dPoint TopLeft(void) const;
3057  const ON_2dPoint BottomRight(void) const;
3058 
3059  bool IntersectRect(const ON_4dRect* r1, const ON_4dRect* r2);
3060  bool IntersectRect(const ON_4dRect& r1, const ON_4dRect& r2);
3061 
3062  bool IsRectEmpty(void) const;
3063  bool IsRectNull(void) const;
3064  void SetRectEmpty(void) { *this = Zero; }
3065  void SetRect(double l, double t, double r, double b);
3066 
3067  bool PtInRect(const ON_2dPoint& pt) const;
3068 
3069  void OffsetRect(double, double);
3070  void OffsetRect(const ON_2dVector&);
3071  void InflateRect(double, double);
3072  void InflateRect(double, double, double, double);
3073  void DeflateRect(double, double);
3074  bool SubtractRect(const ON_4dRect* rect1, const ON_4dRect* rect2);
3075 
3076  void NormalizeRect();
3077 
3078 public:
3079  double left;
3080  double top;
3081  double right;
3082  double bottom;
3083 };
3084 
3085 #if defined(ON_DLL_TEMPLATE)
3086 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_4dRect>;
3087 #endif
3088 
3089 
3090 ON_DECL
3091 bool operator==(const ON_4dRect&, const ON_4dRect&);
3092 
3093 ON_DECL
3094 bool operator!=(const ON_4dRect&, const ON_4dRect&);
3095 
3096 
3097 
3098 
3099 
3100 
3101 
3102 
3103 
3104 #endif
3105 
Definition: opennurbs_point.h:2231
Definition: opennurbs_point.h:2374
Definition: opennurbs_fpoint.h:556
Definition: opennurbs_fpoint.h:832
Definition: opennurbs_point.h:2255
Definition: opennurbs_point.h:1933
static const ON_Interval ZeroToTwoPi
Definition: opennurbs_point.h:51
static const ON_Interval Nan
Definition: opennurbs_point.h:52
Definition: opennurbs_point.h:2335
Definition: opennurbs_point.h:2289
static const ON_Interval ZeroToOne
Definition: opennurbs_point.h:50
Definition: opennurbs_point.h:2356
Definition: opennurbs_point.h:2312
Definition: opennurbs_fpoint.h:211
Definition: opennurbs_point.h:1422
Class ON_2dSize.
Definition: opennurbs_point.h:2844
Definition: opennurbs_point.h:277
Definition: opennurbs_mesh.h:1245
Definition: opennurbs_point.h:2018
Definition: opennurbs_point.h:648
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_point.h:1996
Definition: opennurbs_xform.h:28
Definition: opennurbs_mesh.h:2188
Definition: opennurbs_point.h:2272
Definition: opennurbs_line.h:20
Definition: opennurbs_point.h:2932
Definition: opennurbs_mesh.h:790
static const ON_Interval EmptyInterval
Definition: opennurbs_point.h:49
Definition: opennurbs_bezier.h:150
Definition: opennurbs_fpoint.h:38
Definition: opennurbs_point.h:460
Definition: opennurbs_plane.h:20
Definition: opennurbs_fpoint.h:385
Typically the vector portion is a unit vector and m_d = -(x*P.x + y*P.y + z*P.z) for a point P on the...
Definition: opennurbs_point.h:1433
Definition: opennurbs_point.h:839
Definition: opennurbs_point.h:1152
Definition: opennurbs_point.h:46
Definition: opennurbs_point.h:1973