001/*
002 *   Curve  -- Interface all curve type objects.
003 *
004 *   Copyright (C) 2009-2025, Joseph A. Huwaldt
005 *   All rights reserved.
006 *   
007 *   This library is free software; you can redistribute it and/or
008 *   modify it under the terms of the GNU Lesser General Public
009 *   License as published by the Free Software Foundation; either
010 *   version 2.1 of the License, or (at your option) any later version.
011 *   
012 *   This library is distributed in the hope that it will be useful,
013 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 *   Lesser General Public License for more details.
016 *
017 *   You should have received a copy of the GNU Lesser General Public License
018 *   along with this program; if not, write to the Free Software
019 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020 *   Or visit:  http://www.gnu.org/licenses/lgpl.html
021 */
022package geomss.geom;
023
024import geomss.geom.nurbs.NurbsCurve;
025import jahuwaldt.js.param.Parameter;
026import java.util.List;
027import javax.measure.converter.ConversionException;
028import javax.measure.quantity.Area;
029import javax.measure.quantity.Dimensionless;
030import javax.measure.quantity.Length;
031import javax.measure.unit.Unit;
032
033/**
034 * Defines the interface for {@link GeomElement} objects that are continuous curves.
035 *
036 * <p> Modified by: Joseph A. Huwaldt </p>
037 *
038 * @author Joseph A. Huwaldt, Date: May 15, 2009
039 * @version February 17, 2025
040 *
041 * @param <T> The type of this curve.
042 */
043public interface Curve<T extends Curve> extends GeomElement<T>, ParametricGeometry<T>, Transformable<T> {
044
045    /**
046     * Returns the equivalent to this curve but stated in the specified unit.
047     *
048     * @param unit the length unit of the curve to be returned.
049     * @return an equivalent to this curve but stated in the specified unit.
050     * @throws ConversionException if the the input unit is not a length unit.
051     */
052    @Override
053    public T to(Unit<Length> unit) throws ConversionException;
054
055    /**
056     * Return a copy of this curve converted to the specified number of physical
057     * dimensions. If the number of dimensions is greater than this element, then zeros
058     * are added to the additional dimensions. If the number of dimensions is less than
059     * this element, then the extra dimensions are simply dropped (truncated). If the new
060     * dimensions are the same as the dimension of this element, then this element is
061     * simply returned.
062     *
063     * @param newDim The dimension of the curve to return.
064     * @return This curve converted to the new dimensions.
065     */
066    @Override
067    public abstract T toDimension(int newDim);
068
069    /**
070     * Returns a copy of this curve instance
071     * {@link javolution.context.AllocatorContext allocated} by the calling thread
072     * (possibly on the stack).
073     *
074     * @return an identical and independent copy of this curve.
075     */
076    @Override
077    public T copy();
078
079    /**
080     * Return a copy of this object with any transformations or subranges removed
081     * (applied).
082     */
083    @Override
084    public T copyToReal();
085
086    /**
087     * Return a new curve that is identical to this one, but with the parameterization
088     * reversed.
089     * 
090     * @return A new curve that is identical to this one, but with the parameterization
091     * reversed.
092     */
093    public T reverse();
094
095    /**
096     * Return a NURBS curve representation of this curve to within the specified
097     * tolerance.
098     *
099     * @param tol The greatest possible difference between this curve and the NURBS
100     *            representation returned.
101     * @return A NURBS curve that represents this curve to within the specified tolerance.
102     */
103    public NurbsCurve toNurbs(Parameter<Length> tol);
104
105    /**
106     * Split this curve at the specified parametric position returning a list containing
107     * two curves (a lower curve with smaller parametric positions than "s" and an upper
108     * curve with larger parametric positions).
109     *
110     * @param s The parametric position where this curve should be split (must not be 0 or
111     *          1!).
112     * @return A list containing two curves: 0 == the lower curve, 1 == the upper curve.
113     */
114    public GeomList<T> splitAt(double s);
115
116    /**
117     * Split this curve at the specified parametric position returning a list containing
118     * two curves (a lower curve with smaller parametric positions than "s" and an upper
119     * curve with larger parametric positions).
120     *
121     * @param s The parametric position where this curve should be split (must not be 0 or
122     *          1!). Must be a 1-dimensional point with a value in the range 0 to 1.0,
123     *          non-inclusive. Units are ignored.
124     * @return A list containing two curves: 0 == the lower curve, 1 == the upper curve.
125     */
126    public GeomList<T> splitAt(GeomPoint s);
127
128    /**
129     * Return a subrange point on the curve for the given parametric distance along the
130     * curve.
131     *
132     * @param s parametric distance to calculate a point for (0.0 to 1.0 inclusive).
133     * @return The subrange point or <code>null</code> if the parameter is not in a valid
134     *         range.
135     */
136    public SubrangePoint getPoint(double s);
137
138    /**
139     * Return a subrange point on the curve for the given parametric distance along the
140     * curve.
141     *
142     * @param s parametric distance to calculate a point for. Must be a 1-dimensional
143     *          point with a value in the range 0 to 1.0. Units are ignored.
144     * @return The subrange point
145     */
146    @Override
147    public SubrangePoint getPoint(GeomPoint s);
148
149    /**
150     * Calculate a point on the curve for the given parametric distance along the curve.
151     *
152     * @param s parametric distance to calculate a point for (0.0 to 1.0 inclusive).
153     * @return The calculated point
154     */
155    public Point getRealPoint(double s);
156
157    /**
158     * Calculate a point on the curve for the given parametric distance along the curve.
159     *
160     * @param s parametric distance to calculate a point for. Must be a 1-dimensional
161     *          point with a value in the range 0 to 1.0. Units are ignored.
162     * @return calculated point
163     */
164    @Override
165    public Point getRealPoint(GeomPoint s);
166
167    /**
168     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
169     * respect to parametric position(s) on a parametric object for the given parametric
170     * position on the object, <code>d^{grade}p(s)/d^{grade}s</code>.
171     * <p>
172     * Example:<br>
173     * 1st derivative (grade = 1), this returns <code>[p(s), dp(s)/ds]</code>;<br>
174     * 2nd derivative (grade = 2), this returns <code>[p(s), dp(s)/ds, d^2p(s)/d^2s]</code>; etc.
175     * </p>
176     *
177     * @param s     parametric position to calculate the derivatives for. Must match the
178     *              parametric dimension of this parametric surface and have each value in
179     *              the range 0 to 1.0. Units are ignored.
180     * @param grade The maximum grade to calculate the derivatives for (1=1st derivative,
181     *              2=2nd derivative, etc)
182     * @return A list of lists of derivatives (one list for each parametric dimension).
183     *         Each list contains derivatives up to the specified grade at the specified
184     *         parametric position. Example: for a surface list element 0 is the array of
185     *         derivatives in the 1st parametric dimension (s), then 2nd list element is
186     *         the array of derivatives in the 2nd parametric dimension (t).
187     * @throws IllegalArgumentException if the grade is &lt; 0.
188     */
189    @Override
190    public List<List<Vector<Length>>> getDerivatives(GeomPoint s, int grade);
191
192    /**
193     * Calculate a derivative with respect to parametric distance of the given grade on
194     * the curve for the given parametric distance along the curve,
195     * <code>d^{grade}p(s)/d^{grade}s</code>.
196     * <p>
197     * Example:<br>
198     * 1st derivative (grade = 1), this returns <code>dp(s)/ds</code>;<br>
199     * 2nd derivative (grade = 2), this returns <code>d^2p(s)/d^2s</code>; etc.
200     * </p>
201     *
202     * Note: Cartesian space derivatives can be calculated as follows:
203     * <pre>
204     *      derivative = curve.getDerivative(s, 1);
205     *      dy/dx = (dy/ds)/(dx/ds) = derivative.getValue(1)/derivative.getValue(0),
206     *      dy/dz = (dy/ds)/(dz/ds) = derivative.getValue(1)/derivative.getValue(2),
207     *      etc
208     * </pre>
209     *
210     * @param s     Parametric distance to calculate a derivative for (0.0 to 1.0
211     *              inclusive).
212     * @param grade The grade to calculate the derivative for (1=1st derivative, 2=2nd
213     *              derivative, etc)
214     * @return The specified derivative of the curve at the specified parametric position.
215     * @throws IllegalArgumentException if the grade is &lt; 0.
216     */
217    public Vector<Length> getSDerivative(double s, int grade);
218
219    /**
220     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
221     * respect to parametric distance on the curve for the given parametric distance along
222     * the curve, <code>d^{grade}p(s)/d^{grade}s</code>.
223     * <p>
224     * Example:<br>
225     * 1st derivative (grade = 1), this returns <code>[p(s), dp(s)/ds]</code>;<br>
226     * 2nd derivative (grade = 2), this returns <code>[p(s), dp(s)/ds, d^2p(s)/d^2s]</code>; etc.
227     * </p>
228     *
229     * @param s     parametric distance to calculate the derivatives for. Must be a
230     *              1-dimensional point with a value in the range 0 to 1.0. Units are
231     *              ignored.
232     * @param grade The maximum grade to calculate the derivatives for (1=1st derivative,
233     *              2=2nd derivative, etc)
234     * @return A list of derivatives up to the specified grade of the curve at the
235     *         specified parametric position.
236     * @throws IllegalArgumentException if the grade is &lt; 0.
237     */
238    public List<Vector<Length>> getSDerivatives(GeomPoint s, int grade);
239
240    /**
241     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
242     * respect to parametric distance on the curve for the given parametric distance along
243     * the curve, <code>d^{grade}p(s)/d^{grade}s</code>.
244     * <p>
245     * Example:<br>
246     * 1st derivative (grade = 1), this returns <code>[p(s), dp(s)/ds]</code>;<br>
247     * 2nd derivative (grade = 2), this returns <code>[p(s), dp(s)/ds, d^2p(s)/d^2s]</code>; etc.
248     * </p>
249     *
250     * @param s     Parametric distance to calculate the derivatives for (0.0 to 1.0
251     *              inclusive).
252     * @param grade The maximum grade to calculate the derivatives for (1=1st derivative,
253     *              2=2nd derivative, etc)
254     * @return A list of derivatives up to the specified grade of the curve at the
255     *         specified parametric position.
256     * @throws IllegalArgumentException if the grade is &lt; 0.
257     */
258    public List<Vector<Length>> getSDerivatives(double s, int grade);
259
260    /**
261     * Return the tangent vector for the given parametric distance along the curve. This
262     * vector contains the normalized 1st derivative of the curve with respect to
263     * parametric distance in each component direction: dx/ds/|dp(s)/ds|,
264     * dy/ds/|dp(s)/ds|, dz/ds/|dp(s)/ds|, etc.
265     * <p>
266     * Note: Cartesian space derivatives can be calculated as follows:
267     * <pre>
268     *      tangent = curve.getTangent(s);
269     *      dy/dx = (dy/ds)/(dx/ds) = tangent.getValue(1)/tangent.getValue(0),
270     *      dy/dz = (dy/ds)/(dz/ds) = tangent.getValue(1)/tangent.getValue(2),
271     *      etc
272     * </pre>
273      *
274     * @param s Parametric distance to calculate a tangent vector for (0.0 to 1.0
275     *          inclusive).
276     * @return The tangent vector of the curve at the specified parametric position.
277     */
278    public Vector<Dimensionless> getTangent(double s);
279
280    /**
281     * Return the tangent vector for the given parametric distance along the curve. This
282     * vector contains the normalized 1st derivative of the curve with respect to
283     * parametric distance in each component direction: dx/ds/|dp(s)/ds|,
284     * dy/ds/|dp(s)/ds|, dz/ds/|dp(s)/ds|, etc.
285     * <p>
286     * Note: Cartesian space derivatives can be calculated as follows:
287     * <pre>
288     *      tangent = curve.getTangent(s);
289     *      dy/dx = (dy/ds)/(dx/ds) = tangent.getValue(1)/tangent.getValue(0),
290     *      dy/dz = (dy/ds)/(dz/ds) = tangent.getValue(1)/tangent.getValue(2),
291     *      etc
292     * </pre>
293     *
294     * @param s Parametric distance to calculate a tangent vector for. Must be a
295     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
296     * @return The tangent vector of the curve at the specified parametric position.
297     */
298    public Vector<Dimensionless> getTangent(GeomPoint s);
299
300    /**
301     * Return the principal normal vector for the given parametric distance,
302     * <code>s</code>, along the curve. This vector is normal to the curve, lies in the
303     * normal plane (is perpendicular to the tangent vector), and points toward the center
304     * of curvature at the specified point.
305     *
306     * @param s Parametric distance to calculate the principal normal vector for (0.0 to
307     *          1.0 inclusive).
308     * @return The principal normal vector of the curve at the specified parametric
309     *         position.
310     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
311     * respect to <code>s</code> (if the curve is locally a straight line segment -- this
312     * means there are an infinite number of possible principal normal vectors).
313     */
314    public Vector<Dimensionless> getPrincipalNormal(double s);
315
316    /**
317     * Return the principal normal vector for the given parametric distance,
318     * <code>s</code>, along the curve. This vector is normal to the curve, lies in the
319     * normal plane (is perpendicular to the tangent vector), and points toward the center
320     * of curvature at the specified point.
321     *
322     * @param s Parametric distance to calculate the principal normal vector for. Must be
323     *          a 1-dimensional point with a value in the range 0 to 1.0. Units are
324     *          ignored.
325     * @return The principal normal vector of the curve at the specified parametric
326     *         position.
327     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
328     * respect to <code>s</code> (if the curve is locally a straight line segment -- this
329     * means there are an infinite number of possible principal normal vectors).
330     */
331    public Vector<Dimensionless> getPrincipalNormal(GeomPoint s);
332
333    /**
334     * Return the binormal vector for the given parametric distance along the curve. This
335     * vector is normal to the curve at <code>s</code>, lies in the normal plane (is
336     * perpendicular to the tangent vector), and is perpendicular to the principal normal
337     * vector. Together, the tangent vector, principal normal vector, and binormal vector
338     * form a useful orthogonal frame.
339     *
340     * @param s Parametric distance to calculate the binormal vector for (0.0 to 1.0
341     *          inclusive).
342     * @return The binormal vector of the curve at the specified parametric position.
343     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
344     * respect to <code>s</code> (if the curve is locally a straight line segment).
345     * @throws DimensionException if the curve does not have at least 3 physical
346     * dimensions.
347     */
348    public Vector<Dimensionless> getBinormal(double s) throws DimensionException;
349
350    /**
351     * Return the binormal vector for the given parametric distance along the curve. This
352     * vector is normal to the curve at <code>s</code>, lies in the normal plane (is
353     * perpendicular to the tangent vector), and is perpendicular to the principal normal
354     * vector. Together, the tangent vector, principal normal vector, and binormal vector
355     * form a useful orthogonal frame.
356     *
357     * @param s Parametric distance to calculate the binormal vector for. Must be a
358     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
359     * @return The binormal vector of the curve at the specified parametric position.
360     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
361     * respect to <code>s</code> (if the curve is locally a straight line segment).
362     * @throws DimensionException if the curve does not have at least 3 physical
363     * dimensions.
364     */
365    public Vector<Dimensionless> getBinormal(GeomPoint s) throws DimensionException;
366
367    /**
368     * Return the curvature (kappa = 1/rho; where rho = the radius of curvature) of the
369     * curve at the parametric position <code>s</code>. The curvature vector (vector from
370     * p(s) to the center of curvature) can be constructed from:  <code>k = rhoi*ni</code>
371     * or <code>k = curve.getPrincipalNormal(s).divide(curve.getCurvature(s));</code>
372     *
373     * @param s Parametric distance to calculate the curvature for (0.0 to 1.0 inclusive).
374     * @return The curvature of the curve at the specified parametric position in units of
375     *         1/Length.
376     */
377    public Parameter getCurvature(double s);
378
379    /**
380     * Return the curvature (kappa = 1/rho; where rho = the radius of curvature) of the
381     * curve at the parametric position <code>s</code>. The curvature vector (vector from
382     * p(s) to the center of curvature) can be constructed from:  <code>k = rhoi*ni</code>
383     * or <code>k = curve.getPrincipalNormal(s).divide(curve.getCurvature(s));</code>
384     *
385     * @param s Parametric distance to calculate the curvature for. Must be a
386     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
387     * @return The curvature of the curve at the specified parametric position in units of
388     *         1/Length.
389     */
390    public Parameter getCurvature(GeomPoint s);
391
392    /**
393     * Return the variation of curvature or rate of change of curvature (VOC or
394     * dKappa(s)/ds) at the parametric position <code>s</code>.
395     *
396     * @param s Parametric distance to calculate the variation of curvature for (0.0 to
397     *          1.0 inclusive).
398     * @return The variation of curvature of the curve at the specified parametric
399     *         position in units of 1/Length.
400     */
401    public Parameter getVariationOfCurvature(double s);
402
403    /**
404     * Return the variation of curvature or rate of change of curvature (VOC or
405     * dKappa(s)/ds) at the parametric position <code>s</code>.
406     *
407     * @param s Parametric distance to calculate the variation of curvature for. Must be a
408     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
409     * @return The variation of curvature of the curve at the specified parametric
410     *         position in units of 1/Length.
411     */
412    public Parameter getVariationOfCurvature(GeomPoint s);
413
414    /**
415     * Return the torsion of the curve at the parametric position <code>s</code>. The
416     * torsion is a measure of the rotation or twist about the tangent vector.
417     *
418     * @param s Parametric distance to calculate the torsion for (0.0 to 1.0 inclusive).
419     * @return The torsion of the curve at the specified parametric position in units of
420     *         1/Length.
421     */
422    public Parameter getTorsion(double s);
423
424    /**
425     * Return the torsion of the curve at the parametric position <code>s</code>. The
426     * torsion is a measure of the rotation or twist about the tangent vector.
427     *
428     * @param s Parametric distance to calculate the torsion for. Must be a 1-dimensional
429     *          point with a value in the range 0 to 1.0. Units are ignored.
430     * @return The torsion of the curve at the specified parametric position in units of
431     *         1/Length.
432     */
433    public Parameter getTorsion(GeomPoint s);
434
435    /**
436     * Return the total arc length of this curve.
437     *
438     * @param eps The desired fractional accuracy on the arc-length.
439     * @return The total arc length of the curve.
440     */
441    public Parameter<Length> getArcLength(double eps);
442
443    /**
444     * Return the arc length of a segment of this curve.
445     *
446     * @param s1  The starting parametric distance along the curve to begin the arc-length
447     *            calculation from.
448     * @param s2  The ending parametric distance along the curve to end the arc-length
449     *            calculation at.
450     * @param eps The desired fractional accuracy on the arc-length.
451     * @return The arc length of the specified segment of the curve.
452     */
453    public Parameter<Length> getArcLength(double s1, double s2, double eps);
454
455    /**
456     * Return the arc length of a segment of this curve.
457     *
458     * @param s1  The starting parametric distance along the curve to begin the arc-length
459     *            calculation from. Must be a 1-dimensional point with a value in the
460     *            range 0 to 1.0. Units are ignored.
461     * @param s2  The ending parametric distance along the curve to end the arc-length
462     *            calculation at. Must be a 1-dimensional point with a value in the range
463     *            0 to 1.0. Units are ignored.
464     * @param eps The desired fractional accuracy on the arc-length.
465     * @return The arc length of the specified segment of the curve.
466     */
467    public Parameter<Length> getArcLength(GeomPoint s1, GeomPoint s2, double eps);
468
469    /**
470     * Return a subrange point at the position on the curve with the specified arc-length.
471     *
472     * @param arcLength The target arc length to find in meters.
473     * @param tol       Fractional tolerance (in parameter space) to refine the point
474     *                  position to.
475     * @return A subrange point on the curve at the specified arc-length position.
476     */
477    public SubrangePoint getPointAtArcLength(Parameter<Length> arcLength, double tol);
478
479    /**
480     * A point is found along this curve that when connected by a straight line to the
481     * given point in space, the resulting line is tangent to this curve. This method
482     * should only be used if this curve is a planar curve that is C1 (slope) continuous,
483     * and convex with respect to the point. The given point should be in the plane of the
484     * curve. If it is not, it will be projected into the plane of the curve.
485     *
486     * @param point The point that the tangent on the curve is to be found relative to.
487     * @param near  The parametric distance on the curve (0-1) that serves as an initial
488     *              guess at the location of the tangent point.
489     * @param tol   Fractional tolerance (in parameter space) to refine the point position
490     *              to.
491     * @return The point on this curve that is tangent to the curve and the supplied
492     *         point.
493     */
494    public SubrangePoint getTangencyPoint(GeomPoint point, double near, double tol);
495
496    /**
497     * Return a string of points that are gridded onto the curve using the specified
498     * spacing and gridding rule.
499     *
500     * @param gridRule Specifies whether the subdivision spacing is applied with respect
501     *                 to arc-length in real space or parameter space.
502     * @param spacing  A list of values used to define the subdivision spacing.
503     *                 <code>gridRule</code> specifies whether the subdivision spacing is
504     *                 applied with respect to arc-length in real space or parameter
505     *                 space. If the spacing is arc-length, then the values are
506     *                 interpreted as fractions of the arc length of the curve from 0 to
507     *                 1.
508     * @return A string of subrange points gridded onto the curve at the specified
509     *         parametric positions.
510     */
511    public PointString<SubrangePoint> extractGrid(GridRule gridRule, List<Double> spacing);
512
513    /**
514     * Return a string of points that are gridded onto the curve with the number of points
515     * and spacing chosen to result in straight line segments between the points that are
516     * within the specified tolerance of this curve.
517     *
518     * @param tol The maximum distance that a straight line between gridded points may
519     *            deviate from this curve.
520     * @return A string of subrange points gridded onto the curve.
521     */
522    public PointString<SubrangePoint> gridToTolerance(Parameter<Length> tol);
523
524    /**
525     * Return the intersection between a plane and this curve.
526     *
527     * @param plane The plane to intersect with this curve.
528     * @param tol   Fractional tolerance (in parameter space) to refine the point
529     *              positions to.
530     * @return A PointString containing zero or more subrange points made by the
531     *         intersection of this curve with the specified plane. If no intersection is
532     *         found, an empty PointString is returned.
533     */
534    public PointString<SubrangePoint> intersect(GeomPlane plane, double tol);
535
536    /**
537     * Return the intersection between an infinite line and this curve.
538     *
539     * @param L0   A point on the line (origin of the line).
540     * @param Ldir The direction vector for the line (does not have to be a unit vector).
541     * @param tol  Tolerance (in physical space) to refine the point positions to.
542     * @return A PointString containing zero or more subrange points made by the
543     *         intersection of this curve with the specified line. If no intersection is
544     *         found, an empty PointString is returned.
545     */
546    public PointString<SubrangePoint> intersect(GeomPoint L0, GeomVector Ldir, Parameter<Length> tol);
547
548    /**
549     * Return the intersection between a line segment and this curve.
550     *
551     * @param line The line segment to intersect.
552     * @param tol  Tolerance (in physical space) to refine the point positions to.
553     * @return A list containing two PointString instances each containing zero or more
554     *         subrange points, on this curve and the input line segment respectively,
555     *         made by the intersection of this curve with the specified line segment. If
556     *         no intersections are found a list of two empty PointStrings are returned.
557     */
558    public GeomList<PointString<SubrangePoint>> intersect(LineSegment line, Parameter<Length> tol);
559
560    /**
561     * Return the intersection between another curve and this curve.
562     *
563     * @param curve The curve to intersect with this curve.
564     * @param tol   Tolerance (in physical space) to refine the point positions to.
565     * @return A list containing two PointString instances each containing zero or more
566     *         subrange points, on this curve and the input curve respectively, made by
567     *         the intersection of this curve with the specified curve. If no
568     *         intersections are found a list of two empty PointStrings are returned.
569     */
570    public GeomList<PointString<SubrangePoint>> intersect(Curve curve, Parameter<Length> tol);
571
572    /**
573     * Return the intersections between a surface and this curve.
574     *
575     * @param surface The surface to intersect with this curve.
576     * @param tol     Tolerance (in physical space) to refine the point positions to.
577     * @return A list containing two PointString instances each containing zero or more
578     *         subrange points, on this curve and the input surface respectively, made by
579     *         the intersection of this curve with the specified surface. If no
580     *         intersections are found a list of two empty PointStrings are returned.
581     */
582    public GeomList<PointString<SubrangePoint>> intersect(Surface surface, Parameter<Length> tol);
583
584    /**
585     * Returns the closest point on this curve to the specified point.
586     *
587     * @param point The point to find the closest point on this curve to.
588     * @param tol   Fractional tolerance (in parameter space) to refine the point position
589     *              to.
590     * @return The {@link SubrangePoint} on this curve that is closest to the specified
591     *         point.
592     */
593    @Override
594    public SubrangePoint getClosest(GeomPoint point, double tol);
595
596    /**
597     * Returns the closest point on this curve to the specified point near the specified
598     * parametric position. This may not return the global closest point!
599     *
600     * @param point The point to find the closest point on this curve to.
601     * @param near  The parametric position where the search for the closest point should
602     *              be started.
603     * @param tol   Fractional tolerance (in parameter space) to refine the point position
604     *              to.
605     * @return The point on this curve that is closest to the specified point near the
606     *         specified parametric position.
607     */
608    public SubrangePoint getClosest(GeomPoint point, double near, double tol);
609
610    /**
611     * Returns the closest points on this curve to the specified list of points.
612     *
613     * @param points The list of points to find the closest points on this curve to.
614     * @param tol    Fractional tolerance (in parameter space) to refine the point
615     *               positions to.
616     * @return The list of {@link SubrangePoint} objects on this curve that are closest to
617     *         the specified points.
618     */
619    public PointString<SubrangePoint> getClosest(List<? extends GeomPoint> points, double tol);
620
621    /**
622     * Returns the farthest point on this curve from the specified point.
623     *
624     * @param point The point to find the farthest point on this curve from.
625     * @param tol   Fractional tolerance (in parameter space) to refine the point position
626     *              to.
627     * @return The {@link SubrangePoint} on this curve that is farthest from the specified
628     *         point.
629     */
630    @Override
631    public SubrangePoint getFarthest(GeomPoint point, double tol);
632
633    /**
634     * Returns the farthest point on this curve from the specified point near the
635     * specified parametric position. This may not return the global farthest point!
636     *
637     * @param point The point to find the farthest point on this curve from.
638     * @param near  The parametric position where the search for the farthest point should
639     *              be started.
640     * @param tol   Fractional tolerance (in parameter space) to refine the point position
641     *              to.
642     * @return The {@link SubrangePoint} on this curve that is farthest from the specified
643     *         point.
644     */
645    public SubrangePoint getFarthest(GeomPoint point, double near, double tol);
646
647    /**
648     * Returns the farthest points on this curve to the specified list of points.
649     *
650     * @param points The list of points to find the farthest points on this curve to.
651     * @param tol    Fractional tolerance (in parameter space) to refine the point
652     *               positions to.
653     * @return The list of {@link SubrangePoint} objects on this curve that are farthest
654     *         from the specified points.
655     */
656    public PointString<SubrangePoint> getFarthest(List<? extends GeomPoint> points, double tol);
657
658    /**
659     * Returns the closest points (giving the minimum distance) between this curve and the
660     * specified curve. If the specified curve intersects this curve, then the 1st
661     * intersection found is returned (not all the intersections are found and there is no
662     * guarantee about which intersection will be returned). If the specified curve is
663     * parallel to this curve (all points are equidistant away), then any point between
664     * the two curves could be returned as the "closest".
665     *
666     * @param curve The curve to find the closest points between this curve and that one.
667     * @param tol   Fractional tolerance (in parameter space) to refine the point position
668     *              to.
669     * @return A list containing two SubrangePoint objects that represent the closest
670     *         point on this curve (index 0) and the closest point on the specified curve
671     *         (index 1).
672     */
673    public PointString<SubrangePoint> getClosest(Curve curve, double tol);
674
675    /**
676     * Returns the closest points (giving the minimum distance) between this curve and the
677     * specified surface. If this curve intersects the specified surface, then the 1st
678     * intersection found is returned (not all the intersections are found and there is no
679     * guarantee about which intersection will be returned). If this curve is parallel to
680     * the specified surface (all closest points are equidistant away), then any point on
681     * this curve and the closest point on the target surface will be returned as
682     * "closest".
683     *
684     * @param surface The surface to find the closest points between this curve and that
685     *                surface.
686     * @param tol     Fractional tolerance (in parameter space) to refine the point
687     *                position to.
688     * @return A list containing two SubrangePoint objects that represent the closest
689     *         point on this curve (index 0) and the closest point on the specified
690     *         surface (index 1).
691     */
692    public PointString<SubrangePoint> getClosest(Surface surface, double tol);
693
694    /**
695     * Returns the closest points (giving the minimum distance) between this curve and the
696     * specified plane. If this curve intersects the specified plane, then the 1st
697     * intersection found is returned (not all the intersections are found and there is no
698     * guarantee about which intersection will be returned). If this curve is parallel to
699     * the specified plane (all closest points are equidistant away), then any point on
700     * this curve and the closest point on the target plane will be returned as "closest".
701     *
702     * @param plane The plane to find the closest points between this curve and that
703     *              plane.
704     * @param tol   Fractional tolerance (in parameter space) to refine the point position
705     *              to.
706     * @return The closest point found on this curve to the specified plane.
707     */
708    public SubrangePoint getClosest(GeomPlane plane, double tol);
709
710    /**
711     * Return the signed area of the region enclosed or subtended by a planar curve
712     * relative to the specified reference point. This method assumes that the curve is
713     * planar and will give incorrect results if the curve is not planar. Also, the input
714     * reference point is assumed to lie in the plane of the curve, it if is not, this
715     * will give incorrect results. If the curve is closed, then the reference point is
716     * arbitrary (as long as it is in the plane of the curve). If the curve is open, then
717     * the area returned is that subtended by the curve with straight lines from each end
718     * of the curve to the input point.
719     *
720     * @param refPnt The reference point used for computing the enclosed or subtended area
721     *               of the curve.
722     * @param eps    The desired fractional accuracy of the area calculated.
723     * @return The area enclosed or subtended by this curve (assuming that this curve is
724     *         planar and that the reference point lies in the plane of this curve).
725     */
726    public Parameter<Area> getEnclosedArea(GeomPoint refPnt, double eps);
727
728    /**
729     * Return <code>true</code> if this curve is degenerate (i.e.: has length less than
730     * the specified tolerance).
731     *
732     * @param tol The tolerance for determining if this curve is degenerate. May not be
733     *            null.
734     * @return true if this curve is degenerate.
735     */
736    @Override
737    public boolean isDegenerate(Parameter<Length> tol);
738
739    /**
740     * Return <code>true</code> if this curve is planar or <code>false</code> if it is
741     * not.
742     *
743     * @param tol The geometric tolerance to use in determining if the curve is planar.
744     * @return true if this curve is planar.
745     */
746    public boolean isPlanar(Parameter<Length> tol);
747
748    /**
749     * Returns <code>true</code> if this curve is a line to within the specified
750     * tolerance.
751     *
752     * @param tol The tolerance for determining if this curve is a line.
753     * @return true if this curve is a line.
754     */
755    public boolean isLine(Parameter<Length> tol);
756
757    /**
758     * Returns <code>true</code> if this curve is a circular arc to within the specified
759     * tolerance.
760     *
761     * @param tol The tolerance for determining if this curve is a circular arc.
762     * @return true if this curve is a circular arc.
763     */
764    public boolean isCircular(Parameter<Length> tol);
765
766}