Point Cloud Library (PCL)  1.9.1-dev
opennurbs_curve.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 // Definition of virtual parametric curve
20 //
21 ////////////////////////////////////////////////////////////////
22 
23 #if !defined(OPENNURBS_CURVE_INC_)
24 #define OPENNURBS_CURVE_INC_
25 
26 class ON_Curve;
27 class ON_Plane;
28 class ON_Arc;
29 class ON_NurbsCurve;
30 class ON_CurveTree;
31 
32 
33 ////////////////////////////////////////////////////////////////
34 ////////////////////////////////////////////////////////////////
35 
36 
37 class ON_CLASS ON_MeshCurveParameters
38 {
39 public:
41 
42  // If main_seg_count <= 0, then both these parameters are ignored.
43  // If main_seg_count > 0, then sub_seg_count must be >= 1. In this
44  // case the curve will be broken into main_seg_count equally spaced
45  // chords. If needed, each of these chords can be split into as many
46  // sub_seg_count sub-parts if the subdivision is necessary for the
47  // mesh to meet the other meshing constraints. In particular, if
48  // sub_seg_count = 0, then the curve is broken into main_seg_count
49  // pieces and no further testing is performed.
52 
55 
56  // Maximum angle (in radians) between unit tangents at adjacent
57  // vertices.
59 
60  // Maximum permitted value of
61  // distance chord midpoint to curve) / (length of chord)
62  double m_max_chr;
63 
64  // If max_aspect < 1.0, the parameter is ignored.
65  // If 1 <= max_aspect < sqrt(2), it is treated as if
66  // max_aspect = sqrt(2).
67  // This parameter controls the maximum permitted value of
68  // (length of longest chord) / (length of shortest chord)
69  double m_max_aspect;
70 
71  // If tolerance = 0, the parameter is ignored.
72  // This parameter controls the maximum permitted value of the
73  // distance from the curve to the mesh.
74  double m_tolerance;
75 
76  // If m_min_edge_length = 0, the parameter is ignored.
77  // This parameter controls the minimum permitted edge length.
79 
80  // If max_edge_length = 0, the parameter is ignored.
81  // This parameter controls the maximum permitted edge length.
83 
84  double m_reserved3;
85  double m_reserved4;
86 };
87 
88 class ON_CLASS ON_Curve : public ON_Geometry
89 {
90  // pure virtual class for curve objects
91 
92  // Any object derived from ON_Curve should have a
93  // ON_OBJECT_DECLARE(ON_...);
94  // as the last line of its class definition and a
95  // ON_OBJECT_IMPLEMENT( ON_..., ON_baseclass );
96  // in a .cpp file.
97  //
98  // See the definition of ON_Object for details.
99  ON_OBJECT_DECLARE(ON_Curve);
100 
101 public:
102  // virtual ON_Object::DestroyRuntimeCache override
103  void DestroyRuntimeCache( bool bDelete = true );
104 
105 public:
106  ON_Curve();
107  ON_Curve(const ON_Curve&);
108  ON_Curve& operator=(const ON_Curve&);
109  virtual ~ON_Curve();
110 
111  // virtual ON_Object::SizeOf override
112  unsigned int SizeOf() const;
113 
114  // virtual ON_Geometry override
115  bool EvaluatePoint( const class ON_ObjRef& objref, ON_3dPoint& P ) const;
116 
117  /*
118  Description:
119  Get a duplicate of the curve.
120  Returns:
121  A duplicate of the curve.
122  Remarks:
123  The caller must delete the returned curve.
124  For non-ON_CurveProxy objects, this simply duplicates the curve using
125  ON_Object::Duplicate.
126  For ON_CurveProxy objects, this duplicates the actual proxy curve
127  geometry and, if necessary, trims and reverse the result to that
128  the returned curve's parameterization and locus match the proxy curve's.
129  */
130  virtual
131  ON_Curve* DuplicateCurve() const;
132 
133  // Description:
134  // overrides virtual ON_Object::ObjectType.
135  // Returns:
136  // ON::curve_object
137  ON::object_type ObjectType() const;
138 
139  /*
140  Description:
141  Get tight bounding box of the curve.
142  Parameters:
143  tight_bbox - [in/out] tight bounding box
144  bGrowBox -[in] (default=false)
145  If true and the input tight_bbox is valid, then returned
146  tight_bbox is the union of the input tight_bbox and the
147  curve's tight bounding box.
148  xform -[in] (default=NULL)
149  If not NULL, the tight bounding box of the transformed
150  curve is calculated. The curve is not modified.
151  Returns:
152  True if the returned tight_bbox is set to a valid
153  bounding box.
154  */
155  bool GetTightBoundingBox(
156  ON_BoundingBox& tight_bbox,
157  int bGrowBox = false,
158  const ON_Xform* xform = 0
159  ) const;
160 
161  ////////////////////////////////////////////////////////////////////
162  // curve interface
163 
164  // Description:
165  // Gets domain of the curve
166  // Parameters:
167  // t0 - [out]
168  // t1 - [out] domain is [*t0, *t1]
169  // Returns:
170  // true if successful.
171  ON_BOOL32 GetDomain( double* t0, double* t1 ) const;
172 
173  // Returns:
174  // domain of the curve.
175  virtual
176  ON_Interval Domain() const = 0;
177 
178  /*
179  Description:
180  Set the domain of the curve.
181  Parameters:
182  domain - [in] increasing interval
183  Returns:
184  true if successful.
185  */
186  bool SetDomain( ON_Interval domain );
187 
188  // Description:
189  // Set the domain of the curve
190  // Parameters:
191  // t0 - [in]
192  // t1 - [in] new domain will be [t0,t1]
193  // Returns:
194  // true if successful.
195  virtual
196  ON_BOOL32 SetDomain(
197  double t0,
198  double t1
199  );
200 
201 
202  /*
203  Description:
204  If this curve is closed, then modify it so that
205  the start/end point is at curve parameter t.
206  Parameters:
207  t - [in] curve parameter of new start/end point. The
208  returned curves domain will start at t.
209  Returns:
210  true if successful.
211  */
212  virtual
213  ON_BOOL32 ChangeClosedCurveSeam(
214  double t
215  );
216 
217  /*
218  Description:
219  Change the dimension of a curve.
220  Parameters:
221  desired_dimension - [in]
222  Returns:
223  true if the curve's dimension was already desired_dimension
224  or if the curve's dimension was successfully changed to
225  desired_dimension.
226  */
227  virtual
228  bool ChangeDimension(
229  int desired_dimension
230  );
231 
232 
233  // Description:
234  // Get number of nonempty smooth (c-infinity) spans in curve
235  // Returns:
236  // Number of nonempty smooth (c-infinity) spans.
237  virtual
238  int SpanCount() const = 0;
239 
240  // Description:
241  // Get number of parameters of "knots".
242  // Parameters:
243  // knots - [out] an array of length SpanCount()+1 is filled in
244  // with the parameters where the curve is not smooth (C-infinity).
245  // Returns:
246  // true if successful
247  virtual
248  ON_BOOL32 GetSpanVector(
249  double* knots
250  ) const = 0; //
251 
252  //////////
253  // If t is in the domain of the curve, GetSpanVectorIndex() returns the
254  // span vector index "i" such that span_vector[i] <= t <= span_vector[i+1].
255  // The "side" parameter determines which span is selected when t is at the
256  // end of a span.
257  virtual
258  ON_BOOL32 GetSpanVectorIndex(
259  double t , // [IN] t = evaluation parameter
260  int side, // [IN] side 0 = default, -1 = from below, +1 = from above
261  int* span_vector_index, // [OUT] span vector index
262  ON_Interval* span_domain // [OUT] domain of the span containing "t"
263  ) const;
264 
265  // Description:
266  // Returns maximum algebraic degree of any span
267  // or a good estimate if curve spans are not algebraic.
268  // Returns:
269  // degree
270  virtual
271  int Degree() const = 0;
272 
273  // Description:
274  // Returns maximum algebraic degree of any span
275  // or a good estimate if curve spans are not algebraic.
276  // Returns:
277  // degree
278  virtual
279  ON_BOOL32 GetParameterTolerance( // returns tminus < tplus: parameters tminus <= s <= tplus
280  double t, // [IN] t = parameter in domain
281  double* tminus, // [OUT] tminus
282  double* tplus // [OUT] tplus
283  ) const;
284 
285  // Description:
286  // Test a curve to see if the locus if its points is a line segment.
287  // Parameters:
288  // tolerance - [in] // tolerance to use when checking linearity
289  // Returns:
290  // true if the ends of the curve are farther than tolerance apart
291  // and the maximum distance from any point on the curve to
292  // the line segment connecting the curve's ends is <= tolerance.
293  virtual
294  ON_BOOL32 IsLinear(
295  double tolerance = ON_ZERO_TOLERANCE
296  ) const;
297 
298  /*
299  Description:
300  Several types of ON_Curve can have the form of a polyline including
301  a degree 1 ON_NurbsCurve, an ON_PolylineCurve, and an ON_PolyCurve
302  all of whose segments are some form of polyline. IsPolyline tests
303  a curve to see if it can be represented as a polyline.
304  Parameters:
305  pline_points - [out] if not NULL and true is returned, then the
306  points of the polyline form are returned here.
307  t - [out] if not NULL and true is returned, then the parameters of
308  the polyline points are returned here.
309  Returns:
310  @untitled table
311  0 curve is not some form of a polyline
312  >=2 number of points in polyline form
313  */
314  virtual
315  int IsPolyline(
316  ON_SimpleArray<ON_3dPoint>* pline_points = NULL,
317  ON_SimpleArray<double>* pline_t = NULL
318  ) const;
319 
320  // Description:
321  // Test a curve to see if the locus if its points is an arc or circle.
322  // Parameters:
323  // plane - [in] if not NULL, test is performed in this plane
324  // arc - [out] if not NULL and true is returned, then arc parameters
325  // are filled in
326  // tolerance - [in] tolerance to use when checking
327  // Returns:
328  // ON_Arc.m_angle > 0 if curve locus is an arc between
329  // specified points. If ON_Arc.m_angle is 2.0*ON_PI, then the curve
330  // is a circle.
331  virtual
332  ON_BOOL32 IsArc(
333  const ON_Plane* plane = NULL,
334  ON_Arc* arc = NULL,
335  double tolerance = ON_ZERO_TOLERANCE
336  ) const;
337 
338  /*
339  Description:
340  Parameters:
341  t - [in] curve parameter
342  plane - [in]
343  if not NULL, test is performed in this plane
344  arc - [out]
345  if not NULL and true is returned, then arc parameters
346  are filled in
347  tolerance - [in]
348  tolerance to use when checking
349  t0 - [out]
350  if not NULL, and then *t0 is set to the parameter
351  at the start of the G2 curve segment that was
352  tested.
353  t1 - [out]
354  if not NULL, and then *t0 is set to the parameter
355  at the start of the G2 curve segment that was
356  tested.
357  Returns:
358  True if the paramter t is on a arc segment of the curve.
359  */
360  bool IsArcAt(
361  double t,
362  const ON_Plane* plane = 0,
363  ON_Arc* arc = 0,
364  double tolerance = ON_ZERO_TOLERANCE,
365  double* t0 = 0,
366  double* t1 = 0
367  ) const;
368 
369  virtual
370  bool IsEllipse(
371  const ON_Plane* plane = NULL,
372  ON_Ellipse* ellipse = NULL,
373  double tolerance = ON_ZERO_TOLERANCE
374  ) const;
375 
376  // Description:
377  // Test a curve to see if it is planar.
378  // Parameters:
379  // plane - [out] if not NULL and true is returned,
380  // the plane parameters are filled in.
381  // tolerance - [in] tolerance to use when checking
382  // Returns:
383  // true if there is a plane such that the maximum distance from
384  // the curve to the plane is <= tolerance.
385  virtual
386  ON_BOOL32 IsPlanar(
387  ON_Plane* plane = NULL,
388  double tolerance = ON_ZERO_TOLERANCE
389  ) const;
390 
391  // Description:
392  // Test a curve to see if it lies in a specific plane.
393  // Parameters:
394  // test_plane - [in]
395  // tolerance - [in] tolerance to use when checking
396  // Returns:
397  // true if the maximum distance from the curve to the
398  // test_plane is <= tolerance.
399  virtual
400  ON_BOOL32 IsInPlane(
401  const ON_Plane& test_plane,
402  double tolerance = ON_ZERO_TOLERANCE
403  ) const = 0;
404 
405  /*
406  Description:
407  Decide if it makes sense to close off this curve by moving
408  the endpoint to the start based on start-end gap size and length
409  of curve as approximated by chord defined by 6 points.
410  Parameters:
411  tolerance - [in] maximum allowable distance between start and end.
412  if start - end gap is greater than tolerance, returns false
413  min_abs_size - [in] if greater than 0.0 and none of the interior sampled
414  points are at least min_abs_size from start, returns false.
415  min_rel_size - [in] if greater than 1.0 and chord length is less than
416  min_rel_size*gap, returns false.
417  Returns:
418  true if start and end points are close enough based on above conditions.
419  */
420 
421  bool IsClosable(
422  double tolerance,
423  double min_abs_size = 0.0,
424  double min_rel_size = 10.0
425  ) const;
426 
427  // Description:
428  // Test a curve to see if it is closed.
429  // Returns:
430  // true if the curve is closed.
431  virtual
432  ON_BOOL32 IsClosed() const;
433 
434  // Description:
435  // Test a curve to see if it is periodic.
436  // Returns:
437  // true if the curve is closed and at least C2 at the start/end.
438  virtual
439  ON_BOOL32 IsPeriodic() const;
440 
441  /*
442  Description:
443  Search for a derivatitive, tangent, or curvature
444  discontinuity.
445  Parameters:
446  c - [in] type of continity to test for.
447  t0 - [in] Search begins at t0. If there is a discontinuity
448  at t0, it will be ignored. This makes it
449  possible to repeatedly call GetNextDiscontinuity
450  and step through the discontinuities.
451  t1 - [in] (t0 != t1) If there is a discontinuity at t1 is
452  will be ingored unless c is a locus discontinuity
453  type and t1 is at the start or end of the curve.
454  t - [out] if a discontinuity is found, then *t reports the
455  parameter at the discontinuity.
456  hint - [in/out] if GetNextDiscontinuity will be called
457  repeatedly, passing a "hint" with initial value *hint=0
458  will increase the speed of the search.
459  dtype - [out] if not NULL, *dtype reports the kind of
460  discontinuity found at *t. A value of 1 means the first
461  derivative or unit tangent was discontinuous. A value
462  of 2 means the second derivative or curvature was
463  discontinuous. A value of 0 means teh curve is not
464  closed, a locus discontinuity test was applied, and
465  t1 is at the start of end of the curve.
466  If 'c', the type of continuity to test for
467  is ON::Gsmooth_continuous and the curvature changes
468  from curved to 0 or 0 to curved and there is no
469  tangency kink dtype is returns 3
470  cos_angle_tolerance - [in] default = cos(1 degree) Used only
471  when c is ON::G1_continuous or ON::G2_continuous. If the
472  cosine of the angle between two tangent vectors is
473  <= cos_angle_tolerance, then a G1 discontinuity is reported.
474  curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used
475  only when c is ON::G2_continuous. If K0 and K1 are
476  curvatures evaluated from above and below and
477  |K0 - K1| > curvature_tolerance, then a curvature
478  discontinuity is reported.
479  Returns:
480  Parametric continuity tests c = (C0_continuous, ..., G2_continuous):
481 
482  true if a parametric discontinuity was found strictly
483  between t0 and t1. Note well that all curves are
484  parametrically continuous at the ends of their domains.
485 
486  Locus continuity tests c = (C0_locus_continuous, ...,G2_locus_continuous):
487 
488  true if a locus discontinuity was found strictly between
489  t0 and t1 or at t1 is the at the end of a curve.
490  Note well that all open curves (IsClosed()=false) are locus
491  discontinuous at the ends of their domains. All closed
492  curves (IsClosed()=true) are at least C0_locus_continuous at
493  the ends of their domains.
494  */
495  virtual
496  bool GetNextDiscontinuity(
497  ON::continuity c,
498  double t0,
499  double t1,
500  double* t,
501  int* hint=NULL,
502  int* dtype=NULL,
503  double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
504  double curvature_tolerance=ON_SQRT_EPSILON
505  ) const;
506 
507  /*
508  Description:
509  Test continuity at a curve parameter value.
510  Parameters:
511  c - [in] type of continuity to test for. Read ON::continuity
512  comments for details.
513  t - [in] parameter to test
514  hint - [in] evaluation hint
515  point_tolerance - [in] if the distance between two points is
516  greater than point_tolerance, then the curve is not C0.
517  d1_tolerance - [in] if the difference between two first derivatives is
518  greater than d1_tolerance, then the curve is not C1.
519  d2_tolerance - [in] if the difference between two second derivatives is
520  greater than d2_tolerance, then the curve is not C2.
521  cos_angle_tolerance - [in] default = cos(1 degree) Used only when
522  c is ON::G1_continuous or ON::G2_continuous. If the cosine
523  of the angle between two tangent vectors
524  is <= cos_angle_tolerance, then a G1 discontinuity is reported.
525  curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when
526  c is ON::G2_continuous or ON::Gsmooth_continuous.
527  ON::G2_continuous:
528  If K0 and K1 are curvatures evaluated
529  from above and below and |K0 - K1| > curvature_tolerance,
530  then a curvature discontinuity is reported.
531  ON::Gsmooth_continuous:
532  If K0 and K1 are curvatures evaluated from above and below
533  and the angle between K0 and K1 is at least twice angle tolerance
534  or ||K0| - |K1|| > (max(|K0|,|K1|) > curvature_tolerance,
535  then a curvature discontinuity is reported.
536  Returns:
537  true if the curve has at least the c type continuity at
538  the parameter t.
539  */
540  virtual
541  bool IsContinuous(
542  ON::continuity c,
543  double t,
544  int* hint = NULL,
545  double point_tolerance=ON_ZERO_TOLERANCE,
546  double d1_tolerance=ON_ZERO_TOLERANCE,
547  double d2_tolerance=ON_ZERO_TOLERANCE,
548  double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
549  double curvature_tolerance=ON_SQRT_EPSILON
550  ) const;
551 
552 
553  // Description:
554  // Reverse the direction of the curve.
555  // Returns:
556  // true if curve was reversed.
557  // Remarks:
558  // If reveresed, the domain changes from [a,b] to [-b,-a]
559  virtual
560  ON_BOOL32 Reverse()=0;
561 
562 
563  /*
564  Description:
565  Force the curve to start at a specified point.
566  Parameters:
567  start_point - [in]
568  Returns:
569  true if successful.
570  Remarks:
571  Some end points cannot be moved. Be sure to check return
572  code.
573  See Also:
574  ON_Curve::SetEndPoint
575  ON_Curve::PointAtStart
576  ON_Curve::PointAtEnd
577  */
578  virtual
579  ON_BOOL32 SetStartPoint(
580  ON_3dPoint start_point
581  );
582 
583  /*
584  Description:
585  Force the curve to end at a specified point.
586  Parameters:
587  end_point - [in]
588  Returns:
589  true if successful.
590  Remarks:
591  Some end points cannot be moved. Be sure to check return
592  code.
593  See Also:
594  ON_Curve::SetStartPoint
595  ON_Curve::PointAtStart
596  ON_Curve::PointAtEnd
597  */
598  virtual
599  ON_BOOL32 SetEndPoint(
600  ON_3dPoint end_point
601  );
602 
603  // Description:
604  // Evaluate point at a parameter.
605  // Parameters:
606  // t - [in] evaluation parameter
607  // Returns:
608  // Point (location of curve at the parameter t).
609  // Remarks:
610  // No error handling.
611  // See Also:
612  // ON_Curve::EvPoint
613  // ON_Curve::PointAtStart
614  // ON_Curve::PointAtEnd
615  ON_3dPoint PointAt(
616  double t
617  ) const;
618 
619  // Description:
620  // Evaluate point at the start of the curve.
621  // Parameters:
622  // t - [in] evaluation parameter
623  // Returns:
624  // Point (location of the start of the curve.)
625  // Remarks:
626  // No error handling.
627  // See Also:
628  // ON_Curve::PointAt
629  ON_3dPoint PointAtStart() const;
630 
631  // Description:
632  // Evaluate point at the end of the curve.
633  // Parameters:
634  // t - [in] evaluation parameter
635  // Returns:
636  // Point (location of the end of the curve.)
637  // Remarks:
638  // No error handling.
639  // See Also:
640  // ON_Curve::PointAt
641  ON_3dPoint PointAtEnd() const;
642 
643  // Description:
644  // Evaluate first derivative at a parameter.
645  // Parameters:
646  // t - [in] evaluation parameter
647  // Returns:
648  // First derivative of the curve at the parameter t.
649  // Remarks:
650  // No error handling.
651  // See Also:
652  // ON_Curve::Ev1Der
653  ON_3dVector DerivativeAt(
654  double t
655  ) const;
656 
657  // Description:
658  // Evaluate unit tangent vector at a parameter.
659  // Parameters:
660  // t - [in] evaluation parameter
661  // Returns:
662  // Unit tangent vector of the curve at the parameter t.
663  // Remarks:
664  // No error handling.
665  // See Also:
666  // ON_Curve::EvTangent
667  ON_3dVector TangentAt(
668  double t
669  ) const;
670 
671  // Description:
672  // Evaluate the curvature vector at a parameter.
673  // Parameters:
674  // t - [in] evaluation parameter
675  // Returns:
676  // curvature vector of the curve at the parameter t.
677  // Remarks:
678  // No error handling.
679  // See Also:
680  // ON_Curve::EvCurvature
681  ON_3dVector CurvatureAt(
682  double t
683  ) const;
684 
685  // Description:
686  // Return a 3d frame at a parameter.
687  // Parameters:
688  // t - [in] evaluation parameter
689  // plane - [out] the frame is returned here
690  // Returns:
691  // true if successful
692  // See Also:
693  // ON_Curve::PointAt, ON_Curve::TangentAt,
694  // ON_Curve::Ev1Der, Ev2Der
695  ON_BOOL32 FrameAt( double t, ON_Plane& plane) const;
696 
697  // Description:
698  // Evaluate point at a parameter with error checking.
699  // Parameters:
700  // t - [in] evaluation parameter
701  // point - [out] value of curve at t
702  // side - [in] optional - determines which side to evaluate from
703  // =0 default
704  // <0 to evaluate from below,
705  // >0 to evaluate from above
706  // hint - [in/out] optional evaluation hint used to speed repeated evaluations
707  // Returns:
708  // false if unable to evaluate.
709  // See Also:
710  // ON_Curve::PointAt
711  // ON_Curve::EvTangent
712  // ON_Curve::Evaluate
713  ON_BOOL32 EvPoint(
714  double t,
715  ON_3dPoint& point,
716  int side = 0,
717  int* hint = 0
718  ) const;
719 
720  // Description:
721  // Evaluate first derivative at a parameter with error checking.
722  // Parameters:
723  // t - [in] evaluation parameter
724  // point - [out] value of curve at t
725  // first_derivative - [out] value of first derivative at t
726  // side - [in] optional - determines which side to evaluate from
727  // =0 default
728  // <0 to evaluate from below,
729  // >0 to evaluate from above
730  // hint - [in/out] optional evaluation hint used to speed repeated evaluations
731  // Returns:
732  // false if unable to evaluate.
733  // See Also:
734  // ON_Curve::EvPoint
735  // ON_Curve::Ev2Der
736  // ON_Curve::EvTangent
737  // ON_Curve::Evaluate
738  ON_BOOL32 Ev1Der(
739  double t,
740  ON_3dPoint& point,
741  ON_3dVector& first_derivative,
742  int side = 0,
743  int* hint = 0
744  ) const;
745 
746  // Description:
747  // Evaluate second derivative at a parameter with error checking.
748  // Parameters:
749  // t - [in] evaluation parameter
750  // point - [out] value of curve at t
751  // first_derivative - [out] value of first derivative at t
752  // second_derivative - [out] value of second derivative at t
753  // side - [in] optional - determines which side to evaluate from
754  // =0 default
755  // <0 to evaluate from below,
756  // >0 to evaluate from above
757  // hint - [in/out] optional evaluation hint used to speed repeated evaluations
758  // Returns:
759  // false if unable to evaluate.
760  // See Also:
761  // ON_Curve::Ev1Der
762  // ON_Curve::EvCurvature
763  // ON_Curve::Evaluate
764  ON_BOOL32 Ev2Der(
765  double t,
766  ON_3dPoint& point,
767  ON_3dVector& first_derivative,
768  ON_3dVector& second_derivative,
769  int side = 0,
770  int* hint = 0
771  ) const;
772 
773  /*
774  Description:
775  Evaluate unit tangent at a parameter with error checking.
776  Parameters:
777  t - [in] evaluation parameter
778  point - [out] value of curve at t
779  tangent - [out] value of unit tangent
780  side - [in] optional - determines which side to evaluate from
781  =0 default
782  <0 to evaluate from below,
783  >0 to evaluate from above
784  hint - [in/out] optional evaluation hint used to speed repeated evaluations
785  Returns:
786  false if unable to evaluate.
787  See Also:
788  ON_Curve::TangentAt
789  ON_Curve::Ev1Der
790  */
791  ON_BOOL32 EvTangent(
792  double t,
793  ON_3dPoint& point,
794  ON_3dVector& tangent,
795  int side = 0,
796  int* hint = 0
797  ) const;
798 
799  /*
800  Description:
801  Evaluate unit tangent and curvature at a parameter with error checking.
802  Parameters:
803  t - [in] evaluation parameter
804  point - [out] value of curve at t
805  tangent - [out] value of unit tangent
806  kappa - [out] value of curvature vector
807  side - [in] optional - determines which side to evaluate from
808  =0 default
809  <0 to evaluate from below,
810  >0 to evaluate from above
811  hint - [in/out] optional evaluation hint used to speed repeated evaluations
812  Returns:
813  false if unable to evaluate.
814  See Also:
815  ON_Curve::CurvatureAt
816  ON_Curve::Ev2Der
817  ON_EvCurvature
818  */
819  ON_BOOL32 EvCurvature(
820  double t,
821  ON_3dPoint& point,
822  ON_3dVector& tangent,
823  ON_3dVector& kappa,
824  int side = 0,
825  int* hint = 0
826  ) const;
827 
828  /*
829  Description:
830  This evaluator actually does all the work. The other ON_Curve
831  evaluation tools call this virtual function.
832  Parameters:
833  t - [in] evaluation parameter ( usually in Domain() ).
834  der_count - [in] (>=0) number of derivatives to evaluate
835  v_stride - [in] (>=Dimension()) stride to use for the v[] array
836  v - [out] array of length (der_count+1)*v_stride
837  curve(t) is returned in (v[0],...,v[m_dim-1]),
838  curve'(t) is retuned in (v[v_stride],...,v[v_stride+m_dim-1]),
839  curve"(t) is retuned in (v[2*v_stride],...,v[2*v_stride+m_dim-1]),
840  etc.
841  side - [in] optional - determines which side to evaluate from
842  =0 default
843  <0 to evaluate from below,
844  >0 to evaluate from above
845  hint - [in/out] optional evaluation hint used to speed repeated evaluations
846  Returns:
847  false if unable to evaluate.
848  See Also:
849  ON_Curve::EvPoint
850  ON_Curve::Ev1Der
851  ON_Curve::Ev2Der
852  */
853  virtual
854  ON_BOOL32 Evaluate(
855  double t,
856  int der_count,
857  int v_stride,
858  double* v,
859  int side = 0,
860  int* hint = 0
861  ) const = 0;
862 
863 
864  /*
865  Parameters:
866  min_length -[in]
867  minimum length of a linear span
868  tolerance -[in]
869  distance tolerance to use when checking linearity.
870  Returns
871  true if the span is a non-degenrate line. This means:
872  - dimension = 2 or 3
873  - The length of the the line segment from the span's initial
874  point to the span's control point is >= min_length.
875  - The maximum distance from the line segment to the span
876  is <= tolerance and the span increases monotonically
877  in the direction of the line segment.
878  */
879  bool FirstSpanIsLinear(
880  double min_length,
881  double tolerance
882  ) const;
883 
884  bool LastSpanIsLinear(
885  double min_length,
886  double tolerance
887  ) const;
888 
889  bool FirstSpanIsLinear(
890  double min_length,
891  double tolerance,
892  ON_Line* span_line
893  ) const;
894 
895  bool LastSpanIsLinear(
896  double min_length,
897  double tolerance,
898  ON_Line* span_line
899  ) const;
900 
901  // Description:
902  // Removes portions of the curve outside the specified interval.
903  // Parameters:
904  // domain - [in] interval of the curve to keep. Portions of the
905  // curve before curve(domain[0]) and after curve(domain[1]) are
906  // removed.
907  // Returns:
908  // true if successful.
909  virtual
910  ON_BOOL32 Trim(
911  const ON_Interval& domain
912  );
913 
914  // Description:
915  // Pure virtual function. Default returns false.
916  // Where possible, analytically extends curve to include domain.
917  // Parameters:
918  // domain - [in] if domain is not included in curve domain,
919  // curve will be extended so that its domain includes domain.
920  // Will not work if curve is closed. Original curve is identical
921  // to the restriction of the resulting curve to the original curve domain,
922  // Returns:
923  // true if successful.
924  virtual
925  bool Extend(
926  const ON_Interval& domain
927  );
928 
929  /*
930  Description:
931  Splits (divides) the curve at the specified parameter.
932  The parameter must be in the interior of the curve's domain.
933  The pointers passed to Split must either be NULL or point to
934  an ON_Curve object of the same type. If the pointer is NULL,
935  then a curve will be created in Split(). You may pass "this"
936  as left_side or right_side.
937  Parameters:
938  t - [in] parameter to split the curve at in the
939  interval returned by Domain().
940  left_side - [out] left portion of curve returned here
941  right_side - [out] right portion of curve returned here
942  Returns:
943  true - The curve was split into two pieces.
944  false - The curve could not be split. For example if the parameter is
945  too close to an endpoint.
946 
947  Example:
948  For example, if crv were an ON_NurbsCurve, then
949 
950  ON_NurbsCurve right_side;
951  crv.Split( crv.Domain().Mid() &crv, &right_side );
952 
953  would split crv at the parametric midpoint, put the left side
954  in crv, and return the right side in right_side.
955  */
956  virtual
957  ON_BOOL32 Split(
958  double t,
959  ON_Curve*& left_side,
960  ON_Curve*& right_side
961  ) const;
962 
963  /*
964  Description:
965  Get a NURBS curve representation of this curve.
966  Parameters:
967  nurbs_curve - [out] NURBS representation returned here
968  tolerance - [in] tolerance to use when creating NURBS
969  representation.
970  subdomain - [in] if not NULL, then the NURBS representation
971  for this portion of the curve is returned.
972  Returns:
973  0 unable to create NURBS representation
974  with desired accuracy.
975  1 success - returned NURBS parameterization
976  matches the curve's to wthe desired accuracy
977  2 success - returned NURBS point locus matches
978  the curve's to the desired accuracy and the
979  domain of the NURBS curve is correct. On
980  However, This curve's parameterization and
981  the NURBS curve parameterization may not
982  match to the desired accuracy. This situation
983  happens when getting NURBS representations of
984  curves that have a transendental parameterization
985  like circles
986  Remarks:
987  This is a low-level virtual function. If you do not need
988  the parameterization information provided by the return code,
989  then ON_Curve::NurbsCurve may be easier to use.
990  See Also:
991  ON_Curve::NurbsCurve
992  */
993  virtual
994  int GetNurbForm(
995  ON_NurbsCurve& nurbs_curve,
996  double tolerance = 0.0,
997  const ON_Interval* subdomain = NULL
998  ) const;
999  /*
1000  Description:
1001  Does a NURBS curve representation of this curve.
1002  Parameters:
1003  Returns:
1004  0 unable to create NURBS representation
1005  with desired accuracy.
1006  1 success - NURBS parameterization
1007  matches the curve's to wthe desired accuracy
1008  2 success - NURBS point locus matches
1009  the curve's and the
1010  domain of the NURBS curve is correct.
1011  However, This curve's parameterization and
1012  the NURBS curve parameterization may not
1013  match. This situation
1014  happens when getting NURBS representations of
1015  curves that have a transendental parameterization
1016  like circles
1017  Remarks:
1018  This is a low-level virtual function.
1019  See Also:
1020  ON_Curve::GetNurbForm
1021  ON_Curve::NurbsCurve
1022  */
1023  virtual
1024  int HasNurbForm() const;
1025 
1026  /*
1027  Description:
1028  Get a NURBS curve representation of this curve.
1029  Parameters:
1030  pNurbsCurve - [in/out] if not NULL, this ON_NurbsCurve
1031  will be used to store the NURBS representation
1032  of the curve will be returned.
1033  tolerance - [in] tolerance to use when creating NURBS
1034  representation.
1035  subdomain - [in] if not NULL, then the NURBS representation
1036  for this portion of the curve is returned.
1037  Returns:
1038  NULL or a NURBS representation of the curve.
1039  Remarks:
1040  See ON_Surface::GetNurbForm for important details about
1041  the NURBS surface parameterization.
1042  See Also:
1043  ON_Curve::GetNurbForm
1044  */
1045  ON_NurbsCurve* NurbsCurve(
1046  ON_NurbsCurve* pNurbsCurve = NULL,
1047  double tolerance = 0.0,
1048  const ON_Interval* subdomain = NULL
1049  ) const;
1050 
1051  // Description:
1052  // Convert a NURBS curve parameter to a curve parameter
1053  //
1054  // Parameters:
1055  // nurbs_t - [in] nurbs form parameter
1056  // curve_t - [out] curve parameter
1057  //
1058  // Remarks:
1059  // If GetNurbForm returns 2, this function converts the curve
1060  // parameter to the NURBS curve parameter.
1061  //
1062  // See Also:
1063  // ON_Curve::GetNurbForm, ON_Curve::GetNurbFormParameterFromCurveParameter
1064  virtual
1065  ON_BOOL32 GetCurveParameterFromNurbFormParameter(
1066  double nurbs_t,
1067  double* curve_t
1068  ) const;
1069 
1070  // Description:
1071  // Convert a curve parameter to a NURBS curve parameter.
1072  //
1073  // Parameters:
1074  // curve_t - [in] curve parameter
1075  // nurbs_t - [out] nurbs form parameter
1076  //
1077  // Remarks:
1078  // If GetNurbForm returns 2, this function converts the curve
1079  // parameter to the NURBS curve parameter.
1080  //
1081  // See Also:
1082  // ON_Curve::GetNurbForm, ON_Curve::GetCurveParameterFromNurbFormParameter
1083  virtual
1084  ON_BOOL32 GetNurbFormParameterFromCurveParameter(
1085  double curve_t,
1086  double* nurbs_t
1087  ) const;
1088 
1089 
1090  // Description:
1091  // Destroys the runtime curve tree used to speed closest
1092  // point and intersection calcuations.
1093  // Remarks:
1094  // If the geometry of the curve is modified in any way,
1095  // then call DestroyCurveTree(); The curve tree is
1096  // created as needed.
1097  void DestroyCurveTree();
1098 
1099  /*
1100  Description:
1101  Lookup a parameter in the m_t array, optionally using a built in snap tolerance to
1102  snap a parameter value to an element of m_t.
1103  This function is used by some types derived from ON_Curve to snap parameter values
1104  Parameters:
1105  t - [in] parameter
1106  index -[out] index into m_t such that
1107  if function returns false then
1108 
1109  @table
1110  value condition
1111  -1 t<m_t[0] or m_t is empty
1112  0<=i<=m_t.Count()-2 m_t[i] < t < m_t[i+1]
1113  m_t.Count()-1 t>m_t[ m_t.Count()-1]
1114 
1115  if the function returns true then t is equal to, or is closest to and
1116  within tolerance of m_t[index].
1117 
1118  bEnableSnap-[in] enable snapping
1119  m_t -[in] Array of parameter values to snap to
1120  RelTol -[in] tolerance used in snapping
1121 
1122  Returns:
1123  true if the t is exactly equal to (bEnableSnap==false), or within tolerance of
1124  (bEnableSnap==true) m_t[index].
1125  */
1126 protected:
1127  bool ParameterSearch( double t, int& index, bool bEnableSnap, const ON_SimpleArray<double>& m_t,
1128  double RelTol=ON_SQRT_EPSILON) const;
1129 
1130 private:
1131 };
1132 
1133 #if defined(ON_DLL_TEMPLATE)
1134 // This stuff is here because of a limitation in the way Microsoft
1135 // handles templates and DLLs. See Microsoft's knowledge base
1136 // article ID Q168958 for details.
1137 #pragma warning( push )
1138 #pragma warning( disable : 4231 )
1139 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Curve*>;
1140 #pragma warning( pop )
1141 #endif
1142 
1144 {
1145 public:
1146  ON_CurveArray( int = 0 );
1147  ~ON_CurveArray(); // deletes any non-NULL curves
1148 
1149  bool Write( ON_BinaryArchive& ) const;
1150  bool Read( ON_BinaryArchive& );
1151 
1152  void Destroy(); // deletes curves, sets pointers to NULL, sets count to zero
1153 
1154  bool Duplicate( ON_CurveArray& ) const; // operator= copies the pointer values
1155  // duplicate copies the curves themselves
1156 
1157  /*
1158  Description:
1159  Get tight bounding box of the bezier.
1160  Parameters:
1161  tight_bbox - [in/out] tight bounding box
1162  bGrowBox -[in] (default=false)
1163  If true and the input tight_bbox is valid, then returned
1164  tight_bbox is the union of the input tight_bbox and the
1165  tight bounding box of the bezier curve.
1166  xform -[in] (default=NULL)
1167  If not NULL, the tight bounding box of the transformed
1168  bezier is calculated. The bezier curve is not modified.
1169  Returns:
1170  True if the returned tight_bbox is set to a valid
1171  bounding box.
1172  */
1173  bool GetTightBoundingBox(
1174  ON_BoundingBox& tight_bbox,
1175  int bGrowBox = false,
1176  const ON_Xform* xform = 0
1177  ) const;
1178 };
1179 
1180 /*
1181 Description:
1182  Trim a curve.
1183 Parameters:
1184  curve - [in] curve to trim (not modified)
1185  trim_parameters - [in] trimming parameters
1186  If curve is open, then trim_parameters must be an increasing
1187  interval.If curve is closed, and trim_parameters ins a
1188  decreasing interval, then the portion of the curve across the
1189  start/end is returned.
1190 Returns:
1191  trimmed curve or NULL if input is invalid.
1192 */
1193 ON_DECL
1194 ON_Curve* ON_TrimCurve(
1195  const ON_Curve& curve,
1196  ON_Interval trim_parameters
1197  );
1198 
1199 /*
1200 Description:
1201  Move ends of curves to a common point. Neither curve can be closed or an ON_CurveProxy.
1202  If one is an arc or polycurve with arc at end to change, and the other is not,
1203  then the arc is left unchanged and the other curve is moved to the arc endpoint.
1204  Otherwise, both are moved to the midpoint of the segment between the ends.
1205 Parameters:
1206  Crv0 - [in] first curve to modify.
1207  [out] with one endpoint possibly changed.
1208  end0 - [in] if 0, change start of Crv0. Otherwise change end.
1209  Crv1 - [in] second curve to modify.
1210  [out] with one endpoint possibly changed.
1211  end1 - [in] if 0, change start of Crv1. Otherwise change end.
1212 Returns:
1213  true if the endpoints match. Falsse otherwise,
1214 */
1215 ON_DECL
1216 bool ON_ForceMatchCurveEnds(
1217  ON_Curve& Crv0,
1218  int end0,
1219  ON_Curve& Crv1,
1220  int end1
1221  );
1222 
1223 /*
1224 Description:
1225  Join all contiguous curves of an array of ON_Curves.
1226 Parameters:
1227  InCurves - [in] Array of curves to be joined (not modified)
1228  OutCurves - [out] Resulting joined curves and copies of curves that were not joined to anything
1229  are appended.
1230  join_tol - [in] Distance tolerance used to decide if endpoints are close enough
1231  bPreserveDirection - [in] If true, curve endpoints will be compared to curve startpoints.
1232  If false, all start and endpoints will be compared, and copies of input
1233  curves may be reversed in output.
1234  key - [out] if key is not null, InCurves[i] was joined into OutCurves[key[i]].
1235 Returns:
1236  Number of curves added to Outcurves
1237 Remarks:
1238  Closed curves are copied to OutCurves.
1239  Curves that cannot be joined to others are copied to OutCurves. When curves are joined, the results
1240  are ON_PolyCurves. All members of InCurves must have same dimension, at most 3.
1241  */
1242 ON_DECL
1243 int ON_JoinCurves(const ON_SimpleArray<const ON_Curve*>& InCurves,
1244  ON_SimpleArray<ON_Curve*>& OutCurves,
1245  double join_tol,
1246  bool bPreserveDirection = false,
1247  ON_SimpleArray<int>* key = 0
1248  );
1249 
1250 
1251 /*
1252 Description:
1253  Sort a list of lines so they are geometrically continuous.
1254 Parameters:
1255  line_count - [in] number of lines
1256  line_list - [in] array of lines
1257  index - [out] The input index[] is an array of line_count unused integers.
1258  The returned index[] is a permutation of {0,1,...,line_count-1}
1259  so that the list of lines is in end-to-end order.
1260  bReverse - [out] The input bReverse[] is an array of line_count unused bools.
1261  If the returned value of bReverse[j] is true, then
1262  line_list[index[j]] needs to be reversed.
1263 Returns:
1264  True if successful, false if not.
1265 */
1266 ON_DECL
1267 bool ON_SortLines(
1268  int line_count,
1269  const ON_Line* line_list,
1270  int* index,
1271  bool* bReverse
1272  );
1273 
1274 /*
1275 Description:
1276  Sort a list of lines so they are geometrically continuous.
1277 Parameters:
1278  line_list - [in] array of lines
1279  index - [out] The input index[] is an array of line_count unused integers.
1280  The returned index[] is a permutation of {0,1,...,line_count-1}
1281  so that the list of lines is in end-to-end order.
1282  bReverse - [out] The input bReverse[] is an array of line_count unused bools.
1283  If the returned value of bReverse[j] is true, then
1284  line_list[index[j]] needs to be reversed.
1285 Returns:
1286  True if successful, false if not.
1287 */
1288 ON_DECL
1289 bool ON_SortLines(
1290  const ON_SimpleArray<ON_Line>& line_list,
1291  int* index,
1292  bool* bReverse
1293  );
1294 
1295 /*
1296 Description:
1297  Sort a list of open curves so end of a curve matches the start of the next curve.
1298 Parameters:
1299  curve_count - [in] number of curves
1300  curve_list - [in] array of curve pointers
1301  index - [out] The input index[] is an array of curve_count unused integers.
1302  The returned index[] is a permutation of {0,1,...,curve_count-1}
1303  so that the list of curves is in end-to-end order.
1304  bReverse - [out] The input bReverse[] is an array of curve_count unused bools.
1305  If the returned value of bReverse[j] is true, then
1306  curve_list[index[j]] needs to be reversed.
1307 Returns:
1308  True if successful, false if not.
1309 */
1310 ON_DECL
1311 bool ON_SortCurves(
1312  int curve_count,
1313  const ON_Curve* const* curve_list,
1314  int* index,
1315  bool* bReverse
1316  );
1317 
1318 /*
1319 Description:
1320  Sort a list of curves so end of a curve matches the start of the next curve.
1321 Parameters:
1322  curve - [in] array of curves to sort. The curves themselves are not modified.
1323  index - [out] The input index[] is an array of curve_count unused integers.
1324  The returned index[] is a permutation of {0,1,...,curve_count-1}
1325  so that the list of curves is in end-to-end order.
1326  bReverse - [out] The input bReverse[] is an array of curve_count unused bools.
1327  If the returned value of bReverse[j] is true, then
1328  curve[index[j]] needs to be reversed.
1329 Returns:
1330  True if successful, false if not.
1331 */
1332 ON_DECL
1333 bool ON_SortCurves(
1334  const ON_SimpleArray<const ON_Curve*>& curves,
1335  ON_SimpleArray<int>& index,
1336  ON_SimpleArray<bool>& bReverse
1337  );
1338 
1339 /*
1340 Description:
1341  Sort a list of curves so end of a curve matches the start of the next curve.
1342 Parameters:
1343  curve_count - [in] number of curves
1344  curve - [in] array of curve pointers
1345  index - [out] The input index[] is an array of curve_count unused integers.
1346  The returned index[] is a permutation of {0,1,...,curve_count-1}
1347  so that the list of curves is in end-to-end order.
1348  bReverse - [out] The input bReverse[] is an array of curve_count unused bools.
1349  If the returned value of bReverse[j] is true, then
1350  curve[index[j]] needs to be reversed.
1351 Returns:
1352  True if successful, false if not.
1353 */
1354 ON_DECL
1355 bool ON_SortCurves(
1356  const ON_SimpleArray<ON_Curve*>& curves,
1357  ON_SimpleArray<int>& index,
1358  ON_SimpleArray<bool>& bReverse
1359  );
1360 
1361 /*
1362 Description:
1363  Determine the orientaion (counterclockwise or clockwise) of a closed
1364  planar curve.
1365 Paramters:
1366  curve - [in] simple (no self intersections) closed planar curve
1367  xform - [in] Transformation to map the curve to the xy plane. If the
1368  curve is parallel to the xy plane, you may pass NULL.
1369 Returns:
1370  +1: The curve's orientation is counter clockwise in the xy plane.
1371  -1: The curve's orientation is clockwise in the xy plane.
1372  0: Unable to compute the curve's orientation.
1373 */
1374 ON_DECL
1375 int ON_ClosedCurveOrientation( const ON_Curve& curve, const ON_Xform* xform );
1376 
1377 #endif
virtual void DestroyRuntimeCache(bool bDelete=true)
virtual bool EvaluatePoint(const class ON_ObjRef &objref, ON_3dPoint &P) const
virtual ON_BOOL32 Write(ON_BinaryArchive &binary_archive) const
virtual ON::object_type ObjectType() const
virtual ON_BOOL32 Read(ON_BinaryArchive &binary_archive)
ON_Geometry & operator=(const ON_Geometry &)
virtual unsigned int SizeOf() const
virtual bool GetTightBoundingBox(ON_BoundingBox &tight_bbox, int bGrowBox=false, const ON_Xform *xform=0) const