001/*
002 *   Curve  -- Interface all curve type objects.
003 *
004 *   Copyright (C) 2009-2015, 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 August 31, 2015
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 < 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 < 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     * </p>
274     *
275     * @param s Parametric distance to calculate a tangent vector for (0.0 to 1.0
276     *          inclusive).
277     * @return The tangent vector of the curve at the specified parametric position.
278     */
279    public Vector<Dimensionless> getTangent(double s);
280
281    /**
282     * Return the tangent vector for the given parametric distance along the curve. This
283     * vector contains the normalized 1st derivative of the curve with respect to
284     * parametric distance in each component direction: dx/ds/|dp(s)/ds|,
285     * dy/ds/|dp(s)/ds|, dz/ds/|dp(s)/ds|, etc.
286     * <p>
287     * Note: Cartesian space derivatives can be calculated as follows:
288     * <pre>
289     *      tangent = curve.getTangent(s);
290     *      dy/dx = (dy/ds)/(dx/ds) = tangent.getValue(1)/tangent.getValue(0),
291     *      dy/dz = (dy/ds)/(dz/ds) = tangent.getValue(1)/tangent.getValue(2),
292     *      etc
293     * </pre>
294     * </p>
295     *
296     * @param s Parametric distance to calculate a tangent vector for. Must be a
297     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
298     * @return The tangent vector of the curve at the specified parametric position.
299     */
300    public Vector<Dimensionless> getTangent(GeomPoint s);
301
302    /**
303     * Return the principal normal vector for the given parametric distance,
304     * <code>s</code>, along the curve. This vector is normal to the curve, lies in the
305     * normal plane (is perpendicular to the tangent vector), and points toward the center
306     * of curvature at the specified point.
307     *
308     * @param s Parametric distance to calculate the principal normal vector for (0.0 to
309     *          1.0 inclusive).
310     * @return The principal normal vector of the curve at the specified parametric
311     *         position.
312     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
313     * respect to <code>s</code> (if the curve is locally a straight line segment -- this
314     * means there are an infinite number of possible principal normal vectors).
315     */
316    public Vector<Dimensionless> getPrincipalNormal(double s);
317
318    /**
319     * Return the principal normal vector for the given parametric distance,
320     * <code>s</code>, along the curve. This vector is normal to the curve, lies in the
321     * normal plane (is perpendicular to the tangent vector), and points toward the center
322     * of curvature at the specified point.
323     *
324     * @param s Parametric distance to calculate the principal normal vector for. Must be
325     *          a 1-dimensional point with a value in the range 0 to 1.0. Units are
326     *          ignored.
327     * @return The principal normal vector of the curve at the specified parametric
328     *         position.
329     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
330     * respect to <code>s</code> (if the curve is locally a straight line segment -- this
331     * means there are an infinite number of possible principal normal vectors).
332     */
333    public Vector<Dimensionless> getPrincipalNormal(GeomPoint s);
334
335    /**
336     * Return the binormal vector for the given parametric distance along the curve. This
337     * vector is normal to the curve at <code>s</code>, lies in the normal plane (is
338     * perpendicular to the tangent vector), and is perpendicular to the principal normal
339     * vector. Together, the tangent vector, principal normal vector, and binormal vector
340     * form a useful orthogonal frame.
341     *
342     * @param s Parametric distance to calculate the binormal vector for (0.0 to 1.0
343     *          inclusive).
344     * @return The binormal vector of the curve at the specified parametric position.
345     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
346     * respect to <code>s</code> (if the curve is locally a straight line segment).
347     * @throws DimensionException if the curve does not have at least 3 physical
348     * dimensions.
349     */
350    public Vector<Dimensionless> getBinormal(double s) throws DimensionException;
351
352    /**
353     * Return the binormal vector for the given parametric distance along the curve. This
354     * vector is normal to the curve at <code>s</code>, lies in the normal plane (is
355     * perpendicular to the tangent vector), and is perpendicular to the principal normal
356     * vector. Together, the tangent vector, principal normal vector, and binormal vector
357     * form a useful orthogonal frame.
358     *
359     * @param s Parametric distance to calculate the binormal vector for. Must be a
360     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
361     * @return The binormal vector of the curve at the specified parametric position.
362     * @throws IllegalArgumentException if the curve does not have a 2nd derivative with
363     * respect to <code>s</code> (if the curve is locally a straight line segment).
364     * @throws DimensionException if the curve does not have at least 3 physical
365     * dimensions.
366     */
367    public Vector<Dimensionless> getBinormal(GeomPoint s) throws DimensionException;
368
369    /**
370     * Return the curvature (kappa = 1/rho; where rho = the radius of curvature) of the
371     * curve at the parametric position <code>s</code>. The curvature vector (vector from
372     * p(s) to the center of curvature) can be constructed from:  <code>k = rhoi*ni</code>
373     * or <code>k = curve.getPrincipalNormal(s).divide(curve.getCurvature(s));</code>
374     *
375     * @param s Parametric distance to calculate the curvature for (0.0 to 1.0 inclusive).
376     * @return The curvature of the curve at the specified parametric position in units of
377     *         1/Length.
378     */
379    public Parameter getCurvature(double s);
380
381    /**
382     * Return the curvature (kappa = 1/rho; where rho = the radius of curvature) of the
383     * curve at the parametric position <code>s</code>. The curvature vector (vector from
384     * p(s) to the center of curvature) can be constructed from:  <code>k = rhoi*ni</code>
385     * or <code>k = curve.getPrincipalNormal(s).divide(curve.getCurvature(s));</code>
386     *
387     * @param s Parametric distance to calculate the curvature for. Must be a
388     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
389     * @return The curvature of the curve at the specified parametric position in units of
390     *         1/Length.
391     */
392    public Parameter getCurvature(GeomPoint s);
393
394    /**
395     * Return the variation of curvature or rate of change of curvature (VOC or
396     * dKappa(s)/ds) at the parametric position <code>s</code>.
397     *
398     * @param s Parametric distance to calculate the variation of curvature for (0.0 to
399     *          1.0 inclusive).
400     * @return The variation of curvature of the curve at the specified parametric
401     *         position in units of 1/Length.
402     */
403    public Parameter getVariationOfCurvature(double s);
404
405    /**
406     * Return the variation of curvature or rate of change of curvature (VOC or
407     * dKappa(s)/ds) at the parametric position <code>s</code>.
408     *
409     * @param s Parametric distance to calculate the variation of curvature for. Must be a
410     *          1-dimensional point with a value in the range 0 to 1.0. Units are ignored.
411     * @return The variation of curvature of the curve at the specified parametric
412     *         position in units of 1/Length.
413     */
414    public Parameter getVariationOfCurvature(GeomPoint s);
415
416    /**
417     * Return the torsion of the curve at the parametric position <code>s</code>. The
418     * torsion is a measure of the rotation or twist about the tangent vector.
419     *
420     * @param s Parametric distance to calculate the torsion for (0.0 to 1.0 inclusive).
421     * @return The torsion of the curve at the specified parametric position in units of
422     *         1/Length.
423     */
424    public Parameter getTorsion(double s);
425
426    /**
427     * Return the torsion of the curve at the parametric position <code>s</code>. The
428     * torsion is a measure of the rotation or twist about the tangent vector.
429     *
430     * @param s Parametric distance to calculate the torsion for. Must be a 1-dimensional
431     *          point with a value in the range 0 to 1.0. Units are ignored.
432     * @return The torsion of the curve at the specified parametric position in units of
433     *         1/Length.
434     */
435    public Parameter getTorsion(GeomPoint s);
436
437    /**
438     * Return the total arc length of this curve.
439     *
440     * @param eps The desired fractional accuracy on the arc-length.
441     * @return The total arc length of the curve.
442     */
443    public Parameter<Length> getArcLength(double eps);
444
445    /**
446     * Return the arc length of a segment of this curve.
447     *
448     * @param s1  The starting parametric distance along the curve to begin the arc-length
449     *            calculation from.
450     * @param s2  The ending parametric distance along the curve to end the arc-length
451     *            calculation at.
452     * @param eps The desired fractional accuracy on the arc-length.
453     * @return The arc length of the specified segment of the curve.
454     */
455    public Parameter<Length> getArcLength(double s1, double s2, double eps);
456
457    /**
458     * Return the arc length of a segment of this curve.
459     *
460     * @param s1  The starting parametric distance along the curve to begin the arc-length
461     *            calculation from. Must be a 1-dimensional point with a value in the
462     *            range 0 to 1.0. Units are ignored.
463     * @param s2  The ending parametric distance along the curve to end the arc-length
464     *            calculation at. Must be a 1-dimensional point with a value in the range
465     *            0 to 1.0. Units are ignored.
466     * @param eps The desired fractional accuracy on the arc-length.
467     * @return The arc length of the specified segment of the curve.
468     */
469    public Parameter<Length> getArcLength(GeomPoint s1, GeomPoint s2, double eps);
470
471    /**
472     * Return a subrange point at the position on the curve with the specified arc-length.
473     *
474     * @param arcLength The target arc length to find in meters.
475     * @param tol       Fractional tolerance (in parameter space) to refine the point
476     *                  position to.
477     * @return A subrange point on the curve at the specified arc-length position.
478     */
479    public SubrangePoint getPointAtArcLength(Parameter<Length> arcLength, double tol);
480
481    /**
482     * A point is found along this curve that when connected by a straight line to the
483     * given point in space, the resulting line is tangent to this curve. This method
484     * should only be used if this curve is a planar curve that is C1 (slope) continuous,
485     * and convex with respect to the point. The given point should be in the plane of the
486     * curve. If it is not, it will be projected into the plane of the curve.
487     *
488     * @param point The point that the tangent on the curve is to be found relative to.
489     * @param near  The parametric distance on the curve (0-1) that serves as an initial
490     *              guess at the location of the tangent point.
491     * @param tol   Fractional tolerance (in parameter space) to refine the point position
492     *              to.
493     * @return The point on this curve that is tangent to the curve and the supplied
494     *         point.
495     */
496    public SubrangePoint getTangencyPoint(GeomPoint point, double near, double tol);
497
498    /**
499     * Return a string of points that are gridded onto the curve using the specified
500     * spacing and gridding rule.
501     *
502     * @param gridRule Specifies whether the subdivision spacing is applied with respect
503     *                 to arc-length in real space or parameter space.
504     * @param spacing  A list of values used to define the subdivision spacing.
505     *                 <code>gridRule</code> specifies whether the subdivision spacing is
506     *                 applied with respect to arc-length in real space or parameter
507     *                 space. If the spacing is arc-length, then the values are
508     *                 interpreted as fractions of the arc length of the curve from 0 to
509     *                 1.
510     * @return A string of subrange points gridded onto the curve at the specified
511     *         parametric positions.
512     */
513    public PointString<SubrangePoint> extractGrid(GridRule gridRule, List<Double> spacing);
514
515    /**
516     * Return a string of points that are gridded onto the curve with the number of points
517     * and spacing chosen to result in straight line segments between the points that are
518     * within the specified tolerance of this curve.
519     *
520     * @param tol The maximum distance that a straight line between gridded points may
521     *            deviate from this curve.
522     * @return A string of subrange points gridded onto the curve.
523     */
524    public PointString<SubrangePoint> gridToTolerance(Parameter<Length> tol);
525
526    /**
527     * Return the intersection between a plane and this curve.
528     *
529     * @param plane The plane to intersect with this curve.
530     * @param tol   Fractional tolerance (in parameter space) to refine the point
531     *              positions to.
532     * @return A PointString containing zero or more subrange points made by the
533     *         intersection of this curve with the specified plane. If no intersection is
534     *         found, an empty PointString is returned.
535     */
536    public PointString<SubrangePoint> intersect(GeomPlane plane, double tol);
537
538    /**
539     * Return the intersection between an infinite line and this curve.
540     *
541     * @param L0   A point on the line (origin of the line).
542     * @param Ldir The direction vector for the line (does not have to be a unit vector).
543     * @param tol  Tolerance (in physical space) to refine the point positions to.
544     * @return A PointString containing zero or more subrange points made by the
545     *         intersection of this curve with the specified line. If no intersection is
546     *         found, an empty PointString is returned.
547     */
548    public PointString<SubrangePoint> intersect(GeomPoint L0, GeomVector Ldir, Parameter<Length> tol);
549
550    /**
551     * Return the intersection between a line segment and this curve.
552     *
553     * @param line The line segment to intersect.
554     * @param tol  Tolerance (in physical space) to refine the point positions to.
555     * @return A list containing two PointString instances each containing zero or more
556     *         subrange points, on this curve and the input line segment respectively,
557     *         made by the intersection of this curve with the specified line segment. If
558     *         no intersections are found a list of two empty PointStrings are returned.
559     */
560    public GeomList<PointString<SubrangePoint>> intersect(LineSegment line, Parameter<Length> tol);
561
562    /**
563     * Return the intersection between another curve and this curve.
564     *
565     * @param curve The curve to intersect with this curve.
566     * @param tol   Tolerance (in physical space) to refine the point positions to.
567     * @return A list containing two PointString instances each containing zero or more
568     *         subrange points, on this curve and the input curve respectively, made by
569     *         the intersection of this curve with the specified curve. If no
570     *         intersections are found a list of two empty PointStrings are returned.
571     */
572    public GeomList<PointString<SubrangePoint>> intersect(Curve curve, Parameter<Length> tol);
573
574    /**
575     * Return the intersections between a surface and this curve.
576     *
577     * @param surface The surface to intersect with this curve.
578     * @param tol     Tolerance (in physical space) to refine the point positions to.
579     * @return A list containing two PointString instances each containing zero or more
580     *         subrange points, on this curve and the input surface respectively, made by
581     *         the intersection of this curve with the specified surface. If no
582     *         intersections are found a list of two empty PointStrings are returned.
583     */
584    public GeomList<PointString<SubrangePoint>> intersect(Surface surface, Parameter<Length> tol);
585
586    /**
587     * Returns the closest point on this curve to the specified point.
588     *
589     * @param point The point to find the closest point on this curve to.
590     * @param tol   Fractional tolerance (in parameter space) to refine the point position
591     *              to.
592     * @return The {@link SubrangePoint} on this curve that is closest to the specified
593     *         point.
594     */
595    @Override
596    public SubrangePoint getClosest(GeomPoint point, double tol);
597
598    /**
599     * Returns the closest point on this curve to the specified point near the specified
600     * parametric position. This may not return the global closest point!
601     *
602     * @param point The point to find the closest point on this curve to.
603     * @param near  The parametric position where the search for the closest point should
604     *              be started.
605     * @param tol   Fractional tolerance (in parameter space) to refine the point position
606     *              to.
607     * @return The point on this curve that is closest to the specified point near the
608     *         specified parametric position.
609     */
610    public SubrangePoint getClosest(GeomPoint point, double near, double tol);
611
612    /**
613     * Returns the closest points on this curve to the specified list of points.
614     *
615     * @param points The list of points to find the closest points on this curve to.
616     * @param tol    Fractional tolerance (in parameter space) to refine the point
617     *               positions to.
618     * @return The list of {@link SubrangePoint} objects on this curve that are closest to
619     *         the specified points.
620     */
621    public PointString<SubrangePoint> getClosest(List<? extends GeomPoint> points, double tol);
622
623    /**
624     * Returns the farthest point on this curve from the specified point.
625     *
626     * @param point The point to find the farthest point on this curve from.
627     * @param tol   Fractional tolerance (in parameter space) to refine the point position
628     *              to.
629     * @return The {@link SubrangePoint} on this curve that is farthest from the specified
630     *         point.
631     */
632    @Override
633    public SubrangePoint getFarthest(GeomPoint point, double tol);
634
635    /**
636     * Returns the farthest point on this curve from the specified point near the
637     * specified parametric position. This may not return the global farthest point!
638     *
639     * @param point The point to find the farthest point on this curve from.
640     * @param near  The parametric position where the search for the farthest point should
641     *              be started.
642     * @param tol   Fractional tolerance (in parameter space) to refine the point position
643     *              to.
644     * @return The {@link SubrangePoint} on this curve that is farthest from the specified
645     *         point.
646     */
647    public SubrangePoint getFarthest(GeomPoint point, double near, double tol);
648
649    /**
650     * Returns the farthest points on this curve to the specified list of points.
651     *
652     * @param points The list of points to find the farthest points on this curve to.
653     * @param tol    Fractional tolerance (in parameter space) to refine the point
654     *               positions to.
655     * @return The list of {@link SubrangePoint} objects on this curve that are farthest
656     *         from the specified points.
657     */
658    public PointString<SubrangePoint> getFarthest(List<? extends GeomPoint> points, double tol);
659
660    /**
661     * Returns the closest points (giving the minimum distance) between this curve and the
662     * specified curve. If the specified curve intersects this curve, then the 1st
663     * intersection found is returned (not all the intersections are found and there is no
664     * guarantee about which intersection will be returned). If the specified curve is
665     * parallel to this curve (all points are equidistant away), then any point between
666     * the two curves could be returned as the "closest".
667     *
668     * @param curve The curve to find the closest points between this curve and that one.
669     * @param tol   Fractional tolerance (in parameter space) to refine the point position
670     *              to.
671     * @return A list containing two SubrangePoint objects that represent the closest
672     *         point on this curve (index 0) and the closest point on the specified curve
673     *         (index 1).
674     */
675    public PointString<SubrangePoint> getClosest(Curve curve, double tol);
676
677    /**
678     * Returns the closest points (giving the minimum distance) between this curve and the
679     * specified surface. If this curve intersects the specified surface, then the 1st
680     * intersection found is returned (not all the intersections are found and there is no
681     * guarantee about which intersection will be returned). If this curve is parallel to
682     * the specified surface (all closest points are equidistant away), then any point on
683     * this curve and the closest point on the target surface will be returned as
684     * "closest".
685     *
686     * @param surface The surface to find the closest points between this curve and that
687     *                surface.
688     * @param tol     Fractional tolerance (in parameter space) to refine the point
689     *                position to.
690     * @return A list containing two SubrangePoint objects that represent the closest
691     *         point on this curve (index 0) and the closest point on the specified
692     *         surface (index 1).
693     */
694    public PointString<SubrangePoint> getClosest(Surface surface, double tol);
695
696    /**
697     * Returns the closest points (giving the minimum distance) between this curve and the
698     * specified plane. If this curve intersects the specified plane, then the 1st
699     * intersection found is returned (not all the intersections are found and there is no
700     * guarantee about which intersection will be returned). If this curve is parallel to
701     * the specified plane (all closest points are equidistant away), then any point on
702     * this curve and the closest point on the target plane will be returned as "closest".
703     *
704     * @param plane The plane to find the closest points between this curve and that
705     *              plane.
706     * @param tol   Fractional tolerance (in parameter space) to refine the point position
707     *              to.
708     * @return The closest point found on this curve to the specified plane.
709     */
710    public SubrangePoint getClosest(GeomPlane plane, double tol);
711
712    /**
713     * Return the signed area of the region enclosed or subtended by a planar curve
714     * relative to the specified reference point. This method assumes that the curve is
715     * planar and will give incorrect results if the curve is not planar. Also, the input
716     * reference point is assumed to lie in the plane of the curve, it if is not, this
717     * will give incorrect results. If the curve is closed, then the reference point is
718     * arbitrary (as long as it is in the plane of the curve). If the curve is open, then
719     * the area returned is that subtended by the curve with straight lines from each end
720     * of the curve to the input point.
721     *
722     * @param refPnt The reference point used for computing the enclosed or subtended area
723     *               of the curve.
724     * @param eps    The desired fractional accuracy of the area calculated.
725     * @return The area enclosed or subtended by this curve (assuming that this curve is
726     *         planar and that the reference point lies in the plane of this curve).
727     */
728    public Parameter<Area> getEnclosedArea(GeomPoint refPnt, double eps);
729
730    /**
731     * Return <code>true</code> if this curve is degenerate (i.e.: has length less than
732     * the specified tolerance).
733     *
734     * @param tol The tolerance for determining if this curve is degenerate. May not be
735     *            null.
736     * @return true if this curve is degenerate.
737     */
738    @Override
739    public boolean isDegenerate(Parameter<Length> tol);
740
741    /**
742     * Return <code>true</code> if this curve is planar or <code>false</code> if it is
743     * not.
744     *
745     * @param tol The geometric tolerance to use in determining if the curve is planar.
746     * @return true if this curve is planar.
747     */
748    public boolean isPlanar(Parameter<Length> tol);
749
750    /**
751     * Returns <code>true</code> if this curve is a line to within the specified
752     * tolerance.
753     *
754     * @param tol The tolerance for determining if this curve is a line.
755     * @return true if this curve is a line.
756     */
757    public boolean isLine(Parameter<Length> tol);
758
759    /**
760     * Returns <code>true</code> if this curve is a circular arc to within the specified
761     * tolerance.
762     *
763     * @param tol The tolerance for determining if this curve is a circular arc.
764     * @return true if this curve is a circular arc.
765     */
766    public boolean isCircular(Parameter<Length> tol);
767
768}