001/*
002 *   Surface  -- Interface for all surface type objects.
003 *
004 *   Copyright (C) 2010-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.NurbsSurface;
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.quantity.Volume;
032import javax.measure.unit.Unit;
033
034/**
035 * Defines the interface for {@link GeomElement} objects that are surfaces with 2
036 * parametric dimensions.
037 * 
038 * <p> Modified by: Joseph A. Huwaldt </p>
039 * 
040 * @author Joseph A. Huwaldt, Date: June 14, 2010
041 * @version August 30, 2015
042 *
043 * @param <T> The sub-type of this Surface element.
044 */
045public interface Surface<T extends Surface> extends GeomElement<T>, ParametricGeometry<T>, Transformable<T> {
046
047    /**
048     * Returns the equivalent to this surface but stated in the specified unit.
049     *
050     * @param unit the length unit of the surface to be returned.
051     * @return an equivalent to this surface but stated in the specified unit.
052     * @throws ConversionException if the the input unit is not a length unit.
053     */
054    @Override
055    public T to(Unit<Length> unit) throws ConversionException;
056
057    /**
058     * Return a new surface that is identical to this one but with the transpose of the
059     * parameterization of this surface. The S and T directions will be swapped. This is
060     * an optional method that not all subclasses will provide. Those that do not provide
061     * this method will throw an UnsupportedMethodException.
062     *
063     * @return A new surface, identical to this one, but with the transpose of the
064     * parameterization.
065     * @throws UnsupportedOperationException if this method is not supported.
066     */
067    public T transpose();
068
069    /**
070     * Split this surface at the specified parametric S-position returning a list
071     * containing two new surfaces (a lower surface with smaller S-parametric positions
072     * than "s" and an upper surface with larger S-parametric positions).
073     *
074     * @param s The S-parametric position where this surface should be split (must not be
075     * 0 or 1!).
076     * @return A list containing two surfaces: 0 == the lower surface, 1 == the upper
077     * surface.
078     */
079    public GeomList<T> splitAtS(double s);
080
081    /**
082     * Split this surface at the specified parametric S-position returning a list
083     * containing two new surfaces (a lower surface with smaller S-parametric positions
084     * than "s" and an upper surface with larger S-parametric positions).
085     *
086     * @param st The S-parametric position where this surface should be split (must not be
087     * 0 or 1!). Must be a 2-dimensional point with each value in the range 0 to 1, only
088     * the 1st value is used. Units are ignored.
089     * @return A list containing two surfaces: 0 == the lower surface, 1 == the upper
090     * surface.
091     */
092    public GeomList<T> splitAtS(GeomPoint st);
093
094    /**
095     * Split this surface at the specified parametric T-position returning a list
096     * containing two new surfaces (a lower surface with smaller T-parametric positions
097     * than "t" and an upper surface with larger T-parametric positions).
098     *
099     * @param t The T-parametric position where this surface should be split (must not be
100     * 0 or 1!).
101     * @return A list containing two surfaces: 0 == the lower surface, 1 == the upper
102     * surface.
103     */
104    public GeomList<T> splitAtT(double t);
105
106    /**
107     * Split this surface at the specified parametric T-position returning a list
108     * containing two new surfaces (a lower surface with smaller T-parametric positions
109     * than "t" and an upper surface with larger T-parametric positions).
110     *
111     * @param st The T-parametric position where this surface should be split (must not be
112     * 0 or 1!). Must be a 2-dimensional point with each value in the range 0 to 1, only
113     * the 2nd value is used. Units are ignored.
114     * @return A list containing two surfaces: 0 == the lower surface, 1 == the upper
115     * surface.
116     */
117    public GeomList<T> splitAtT(GeomPoint st);
118
119    /**
120     * Return a new surface that is identical to this one, but with the S-parameterization
121     * reversed.
122     *
123     * @return A new surface that is identical to this one, but with the
124     * S-parameterization reversed.
125     * @see #reverseT
126     */
127    public T reverseS();
128
129    /**
130     * Return a new surface that is identical to this one, but with the T-parameterization
131     * reversed.
132     *
133     * @return A new surface that is identical to this one, but with the
134     * T-parameterization reversed.
135     * @see #reverseS
136     */
137    public T reverseT();
138
139    /**
140     * Returns a copy of this ParametricGeometry instance
141     * {@link javolution.context.AllocatorContext allocated} by the calling thread
142     * (possibly on the stack).
143     *
144     * @return an identical and independent copy of this object.
145     */
146    @Override
147    public T copy();
148
149    /**
150     * Return a copy of this surface converted to the specified number of physical
151     * dimensions. If the number of dimensions is greater than this element, then zeros
152     * are added to the additional dimensions. If the number of dimensions is less than
153     * this element, then the extra dimensions are simply dropped (truncated). If the new
154     * dimensions are the same as the dimension of this element, then this element is
155     * simply returned.
156     *
157     * @param newDim The dimension of the surface to return.
158     * @return This surface converted to the new dimensions.
159     */
160    @Override
161    public T toDimension(int newDim);
162
163    /**
164     * Return a NURBS surface representation of this surface to within the specified
165     * tolerance.
166     *
167     * @param tol The greatest possible difference between this surface and the NURBS
168     * representation returned.
169     * @return A NURBS surface that represents this surface to within the specified
170     * tolerance.
171     */
172    public NurbsSurface toNurbs(Parameter<Length> tol);
173
174    /**
175     * Return a subrange point on the surface for the given parametric position on the
176     * surface.
177     *
178     * @param s 1st parametric dimension distance to calculate a point for (0.0 to 1.0
179     * inclusive).
180     * @param t 2nd parametric dimension distance to calculate a point for (0.0 to 1.0
181     * inclusive).
182     * @return The subrange point on the surface at the specified parameter values.
183     * @throws IllegalArgumentException if there is any problem with the parameter values.
184     */
185    public SubrangePoint getPoint(double s, double t);
186
187    /**
188     * Return a subrange point on the surface for the given parametric position on the
189     * surface.
190     *
191     * @param st The parametric position to calculate a point for. Must be a 2-dimensional
192     * point with each value in the range 0 to 1.0. Units are ignored.
193     * @return The subrange point on the surface at the specified parameter values.
194     * @throws IllegalArgumentException if there is any problem with the parameter values.
195     */
196    @Override
197    public SubrangePoint getPoint(GeomPoint st);
198
199    /**
200     * Calculate a point on the surface for the given parametric position on the surface.
201     *
202     * @param s 1st parametric dimension distance to calculate a point for (0.0 to 1.0
203     * inclusive).
204     * @param t 2nd parametric dimension distance to calculate a point for (0.0 to 1.0
205     * inclusive).
206     * @return The calculated point on the surface at the specified parameter values.
207     * @throws IllegalArgumentException if there is any problem with the parameter values.
208     */
209    public Point getRealPoint(double s, double t);
210
211    /**
212     * Calculate a point on the surface for the given parametric position on the surface.
213     *
214     * @param st The parametric position to calculate a point for. Must be a 2-dimensional
215     * point with each value in the range 0 to 1.0. Units are ignored.
216     * @return The calculated point on the surface at the specified parameter values.
217     * @throws IllegalArgumentException if there is any problem with the parameter values.
218     */
219    @Override
220    public Point getRealPoint(GeomPoint st);
221
222    /**
223     * Return a subrange curve on the surface for the given parametric position curve.
224     *
225     * @param pcrv A curve in parametric space indicating the parametric positions on the
226     * the surface represented by the subrange curve. Must be 2D with values between 0 and 1.
227     * @return The subrange curve on the surface at the specified parametric curve positions.
228     */
229    public SubrangeCurve getCurve(Curve pcrv);
230
231    /**
232     * Return a subrange curve at a constant parametric s-value.
233     *
234     * @param s The parametric s-position to extract a subrange curve.
235     * @return The subrange curve on the surface at the specified s-value.
236     * @throws IllegalArgumentException if there is any problem with the parameter value.
237     */
238    public SubrangeCurve getSCurve(double s);
239
240    /**
241     * Return a subrange curve at a constant parametric t-value.
242     *
243     * @param t The parametric t-position to extract a subrange curve.
244     * @return The subrange curve on the surface at the specified t-value.
245     * @throws IllegalArgumentException if there is any problem with the parameter value.
246     */
247    public SubrangeCurve getTCurve(double t);
248
249    /**
250     * Return the T=0 Boundary for this surface as a curve.
251     *
252     * @return The T=0 boundary for this surface as a curve.
253     */
254    public Curve getT0Curve();
255
256    /**
257     * Return the T=1 Boundary for this surface as a curve.
258     *
259     * @return The T=1 boundary for this surface as a curve.
260     */
261    public Curve getT1Curve();
262
263    /**
264     * Return the S=0 Boundary for this surface as a curve.
265     *
266     * @return The S=0 boundary for this surface as a curve.
267     */
268    public Curve getS0Curve();
269
270    /**
271     * Return the S=1 Boundary for this surface as a curve.
272     *
273     * @return The S=1 boundary for this surface as a curve.
274     */
275    public Curve getS1Curve();
276
277    /**
278     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
279     * respect to parametric position(s) on a parametric object for the given parametric
280     * position on the object, <code>d^{grade}p(s)/d^{grade}s</code>.
281     * <p>
282     * Example:<br>
283     * 1st derivative (grade = 1), this returns <code>[p(s), dp(s)/ds]</code>;<br>
284     * 2nd derivative (grade = 2), this returns <code>[p(s), dp(s)/ds, d^2p(s)/d^2s]</code>; etc.
285     * </p>
286     *
287     * @param st The parametric position to calculate the derivatives for. Must match the
288     * parametric dimension of this parametric surface and have each value in the range 0
289     * to 1.0. Units are ignored.
290     * @param grade The maximum grade to calculate the derivatives for (1=1st derivative,
291     * 2=2nd derivative, etc)
292     * @return A list of lists of derivatives (one list for each parametric dimension).
293     * Each list contains derivatives up to the specified grade at the specified
294     * parametric position. Example: for a surface list element 0 is the array of
295     * derivatives int the 1st parametric dimension (s), then 2nd list element is the
296     * array of derivatives in the 2nd parametric dimension (t).
297     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
298     * invalid.
299     */
300    @Override
301    public List<List<Vector<Length>>> getDerivatives(GeomPoint st, int grade);
302
303    /**
304     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
305     * respect to parametric s-position on the surface for the given parametric position
306     * on the surface, <code>d^{grade}p(s,t)/d^{grade}s</code>.
307     * <p>
308     * Example:<br>
309     * 1st derivative (grade = 1), this returns <code>[p(s,t), dp(s,t)/ds]</code>;<br>
310     * 2nd derivative (grade = 2), this returns <code>[p(s,t), dp(s,t)/ds, d^2p(s,t)/d^2s]</code>; etc.
311     * </p>
312     *
313     * @param s 1st parametric dimension distance to calculate derivative for (0.0 to 1.0
314     * inclusive).
315     * @param t 2nd parametric dimension distance to calculate derivative for (0.0 to 1.0
316     * inclusive).
317     * @param grade The maximum grade to calculate the u-derivatives for (1=1st
318     * derivative, 2=2nd derivative, etc)
319     * @return A list of s-derivatives up to the specified grade of the surface at the
320     * specified parametric position.
321     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
322     * invalid.
323     */
324    public List<Vector<Length>> getSDerivatives(double s, double t, int grade);
325
326    /**
327     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
328     * respect to parametric s-position on the surface for the given parametric position
329     * on the surface, <code>d^{grade}p(s,t)/d^{grade}s</code>.
330     * <p>
331     * Example:<br>
332     * 1st derivative (grade = 1), this returns <code>[p(s,t), dp(s,t)/ds]</code>;<br>
333     * 2nd derivative (grade = 2), this returns <code>[p(s,t), dp(s,t)/ds, d^2p(s,t)/d^2s]</code>; etc.
334     * </p>
335     *
336     * @param st The parametric position to calculate the derivatives for. Must be a
337     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
338     * @param grade The maximum grade to calculate the derivatives for (1=1st derivative,
339     * 2=2nd derivative, etc)
340     * @return A list of s-derivatives up to the specified grade of the surface at the
341     * specified parametric position.
342     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
343     * invalid.
344     */
345    public List<Vector<Length>> getSDerivatives(GeomPoint st, int grade);
346
347    /**
348     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
349     * respect to parametric t-position on the surface for the given parametric position
350     * on the surface, <code>d^{grade}p(s,t)/d^{grade}t</code>.
351     * <p>
352     * Example:<br>
353     * 1st derivative (grade = 1), this returns <code>[p(s,t), dp(s,t)/dt]</code>;<br>
354     * 2nd derivative (grade = 2), this returns <code>[p(s,t), dp(s,t)/dt, d^2p(s,t)/d^2t]</code>; etc.
355     * </p>
356     *
357     * @param s 1st parametric dimension distance to calculate derivative for (0.0 to 1.0
358     * inclusive).
359     * @param t 2nd parametric dimension distance to calculate derivative for (0.0 to 1.0
360     * inclusive).
361     * @param grade The maximum grade to calculate the v-derivatives for (1=1st
362     * derivative, 2=2nd derivative, etc)
363     * @return A list of t-derivatives up to the specified grade of the surface at the
364     * specified parametric position.
365     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
366     * invalid.
367     */
368    public List<Vector<Length>> getTDerivatives(double s, double t, int grade);
369
370    /**
371     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
372     * respect to parametric t-position on the surface for the given parametric position
373     * on the surface, <code>d^{grade}p(s,t)/d^{grade}t</code>.
374     * <p>
375     * Example:<br>
376     * 1st derivative (grade = 1), this returns <code>[p(s,t), dp(s,t)/dt]</code>;<br>
377     * 2nd derivative (grade = 2), this returns <code>[p(s,t), dp(s,t)/dt, d^2p(s,t)/d^2t]</code>; etc.
378     * </p>
379     *
380     * @param st The parametric position to calculate the derivatives for. Must be a
381     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
382     * @param grade The maximum grade to calculate the derivatives for (1=1st derivative,
383     * 2=2nd derivative, etc)
384     * @return A list of t-derivatives up to the specified grade of the surface at the
385     * specified parametric position.
386     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
387     * invalid.
388     */
389    public List<Vector<Length>> getTDerivatives(GeomPoint st, int grade);
390
391    /**
392     * Calculate a derivative with respect to parametric s-distance of the given grade on
393     * the surface for the given parametric position on the surface,
394     * <code>d^{grade}p(s,t)/d^{grade}s</code>.
395     * <p>
396     * Example:<br>
397     * 1st derivative (grade = 1), this returns <code>dp(s,t)/ds</code>;<br>
398     * 2nd derivative (grade = 2), this returns <code>d^2p(s,t)/d^2s</code>; etc.
399     * </p>
400     *
401     * @param st The parametric position to calculate the derivative for. Must be a
402     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
403     * @param grade The grade to calculate the derivative for (1=1st derivative, 2=2nd
404     * derivative, etc)
405     * @return The specified s-derivative of the surface at the specified parametric
406     * position.
407     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
408     * invalid.
409     */
410    public Vector<Length> getSDerivative(GeomPoint st, int grade);
411
412    /**
413     * Calculate a derivative with respect to parametric t-distance of the given grade on
414     * the surface for the given parametric position on the surface,
415     * <code>d^{grade}p(s,t)/d^{grade}t</code>.
416     * <p>
417     * Example:<br>
418     * 1st derivative (grade = 1), this returns <code>dp(s,t)/dt</code>;<br>
419     * 2nd derivative (grade = 2), this returns <code>d^2p(s,t)/d^2t</code>; etc.
420     * </p>
421     *
422     * @param st The parametric position to calculate the derivative for. Must be a
423     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
424     * @param grade The grade to calculate the derivative for (1=1st derivative, 2=2nd
425     * derivative, etc)
426     * @return The specified t-derivative of the surface at the specified parametric
427     * position.
428     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
429     * invalid.
430     */
431    public Vector<Length> getTDerivative(GeomPoint st, int grade);
432
433    /**
434     * Calculate a derivative with respect to parametric s-distance of the given grade on
435     * the surface for the given parametric position on the surface,
436     * <code>d^{grade}p(s,t)/d^{grade}s</code>.
437     * <p>
438     * Example:<br>
439     * 1st derivative (grade = 1), this returns <code>dp(s,t)/ds</code>;<br>
440     * 2nd derivative (grade = 2), this returns <code>d^2p(s,t)/d^2s</code>; etc.
441     * </p>
442     *
443     * @param s 1st parametric dimension distance to calculate derivative for (0.0 to 1.0
444     * inclusive).
445     * @param t 2nd parametric dimension distance to calculate derivative for (0.0 to 1.0
446     * inclusive).
447     * @param grade The grade to calculate the derivative for (1=1st derivative, 2=2nd
448     * derivative, etc)
449     * @return The specified s-derivative of the surface at the specified parametric
450     * position.
451     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
452     * invalid.
453     */
454    public Vector<Length> getSDerivative(double s, double t, int grade);
455
456    /**
457     * Calculate all the derivatives from <code>0</code> to <code>grade</code> with
458     * respect to parametric t-position on the surface for the given parametric position
459     * on the surface, <code>d^{grade}p(s,t)/d^{grade}t</code>.
460     * <p>
461     * Example:<br>
462     * 1st derivative (grade = 1), this returns <code>[p(s,t), dp(s,t)/dt]</code>;<br>
463     * 2nd derivative (grade = 2), this returns <code>[p(s,t), dp(s,t)/dt, d^2p(s,t)/d^2t]</code>; etc.
464     * </p>
465     *
466     * @param s 1st parametric dimension distance to calculate derivative for (0.0 to 1.0
467     * inclusive).
468     * @param t 2nd parametric dimension distance to calculate derivative for (0.0 to 1.0
469     * inclusive).
470     * @param grade The maximum grade to calculate the v-derivatives for (1=1st
471     * derivative, 2=2nd derivative, etc)
472     * @return The specified t-derivative of the surface at the specified parametric
473     * position.
474     * @throws IllegalArgumentException if the grade is &lt; 0 or the parameter values are
475     * invalid.
476     */
477    public Vector<Length> getTDerivative(double s, double t, int grade);
478
479    /**
480     * Calculate the twist vector (d^2P/(ds*dt) = d(dP/ds)/dt) for this surface at the
481     * specified position on this surface.
482     *
483     * @param s 1st parametric dimension distance to calculate twist vector for (0.0 to
484     * 1.0 inclusive).
485     * @param t 2nd parametric dimension distance to calculate twist vector for (0.0 to
486     * 1.0 inclusive).
487     * @return The twist vector of this surface at the specified parametric position.
488     * @throws IllegalArgumentException if the parameter values are invalid.
489     */
490    public Vector<Length> getTwistVector(double s, double t);
491
492    /**
493     * Calculate the twist vector (d^2P/(ds*dt) = d(dP/ds)/dt) for this surface at the
494     * specified position on this surface.
495     *
496     * @param st The parametric position to calculate the twist vector for. Must be a
497     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
498     * @return The twist vector of this surface at the specified parametric position.
499     * @throws IllegalArgumentException if the parameter values are invalid.
500     */
501    public Vector<Length> getTwistVector(GeomPoint st);
502
503    /**
504     * Return the normal vector for this surface at the given parametric position (s,t) on
505     * this surface.
506     *
507     * @param s 1st parametric dimension distance to calculate normal for (0.0 to 1.0
508     * inclusive).
509     * @param t 2nd parametric dimension distance to calculate normal for (0.0 to 1.0
510     * inclusive).
511     * @return The normal vector of the surface at the specified parametric position.
512     */
513    public Vector<Dimensionless> getNormal(double s, double t);
514
515    /**
516     * Return the normal vector for this surface at the given parametric position (s,t) on
517     * this surface.
518     *
519     * @param st The parametric position to calculate the normal for. Must be a
520     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
521     * @return The normal vector of the surface at the specified parametric position.
522     */
523    public Vector<Dimensionless> getNormal(GeomPoint st);
524
525    /**
526     * Return the tangent plane to this surface at the given parametric position (s,t) on
527     * this surface.
528     *
529     * @param s 1st parametric dimension distance to calculate tangent plane for (0.0 to
530     * 1.0 inclusive).
531     * @param t 2nd parametric dimension distance to calculate tangent plane for (0.0 to
532     * 1.0 inclusive).
533     * @return The tangent plane of the surface at the specified parametric position.
534     */
535    public Plane getTangentPlane(double s, double t);
536
537    /**
538     * Return the tangent plane to this surface at the given parametric position (s,t) on
539     * this surface.
540     *
541     * @param st The parametric position to calculate the tangent plane for. Must be a
542     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
543     * @return The tangent plane of the surface at the specified parametric position.
544     */
545    public Plane getTangentPlane(GeomPoint st);
546
547    /**
548     * Returns the Gaussian Curvature for this surface at the given parametric position
549     * (s,t) on this surface.
550     *
551     * @param s 1st parametric dimension distance to calculate curvature for (0.0 to 1.0
552     * inclusive).
553     * @param t 2nd parametric dimension distance to calculate curvature for (0.0 to 1.0
554     * inclusive).
555     * @return The Gaussian curvature of the surface at the specified parametric position
556     * in units of 1/Length^2.
557     */
558    public Parameter getGaussianCurvature(double s, double t);
559
560    /**
561     * Returns the Gaussian Curvature for this surface at the given parametric position
562     * (s,t) on this surface.
563     *
564     * @param st The parametric position to calculate the curvature for. Must be a
565     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
566     * @return The Gaussian curvature of the surface at the specified parametric position
567     * in units of 1/Length^2.
568     */
569    public Parameter getGaussianCurvature(GeomPoint st);
570
571    /**
572     * Returns the Mean Curvature for this surface at the given parametric position (s,t)
573     * on this surface.
574     *
575     * @param s 1st parametric dimension distance to calculate curvature for (0.0 to 1.0
576     * inclusive).
577     * @param t 2nd parametric dimension distance to calculate curvature for (0.0 to 1.0
578     * inclusive).
579     * @return The Mean curvature of the surface at the specified parametric position in
580     * units of 1/Length.
581     */
582    public Parameter getMeanCurvature(double s, double t);
583
584    /**
585     * Returns the Mean Curvature for this surface at the given parametric position (s,t)
586     * on this surface.
587     *
588     * @param st The parametric position to calculate the curvature for. Must be a
589     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
590     * @return The Mean curvature of the surface at the specified parametric position in
591     * units of 1/Length.
592     */
593    public Parameter getMeanCurvature(GeomPoint st);
594
595    /**
596     * Return the surface area of this entire surface.
597     *
598     * @param eps The desired fractional accuracy on the surface area.
599     * @return the surface area of this surface.
600     */
601    public Parameter<Area> getArea(double eps);
602
603    /**
604     * Return the surface area of a portion of this surface.
605     *
606     * @param s1 The starting 1st parametric dimension distance to calculate area for (0.0
607     * to 1.0 inclusive).
608     * @param t1 The starting 2nd parametric dimension distance to calculate area for (0.0
609     * to 1.0 inclusive).
610     * @param s2 The ending 1st parametric dimension distance to calculate area for (0.0
611     * to 1.0 inclusive).
612     * @param t2 The ending 2nd parametric dimension distance to calculate area for (0.0
613     * to 1.0 inclusive).
614     * @param eps The desired fractional accuracy on the surface area.
615     * @return the surface area of a portion of this surface.
616     */
617    public Parameter<Area> getArea(double s1, double t1, double s2, double t2, double eps);
618
619    /**
620     * Return the surface area of a portion of this surface.
621     *
622     * @param st1 The starting parametric position to calculate the area for. Must be a
623     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
624     * @param st2 The ending parametric position to calculate the area for. Must be a
625     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
626     * @param eps The desired fractional accuracy on the surface area.
627     * @return the surface area of a portion of this surface.
628     */
629    public Parameter<Area> getArea(GeomPoint st1, GeomPoint st2, double eps);
630
631    /**
632     * Return the enclosed volume of this entire surface.
633     *
634     * @param eps The desired fractional accuracy on the enclosed volume.
635     * @return the enclosed volume of this surface.
636     */
637    public Parameter<Volume> getVolume(double eps);
638
639    /**
640     * Return the enclosed volume of a portion of this surface.
641     *
642     * @param s1 The starting 1st parametric dimension distance to calculate volume for
643     * (0.0 to 1.0 inclusive).
644     * @param t1 The starting 2nd parametric dimension distance to calculate volume for
645     * (0.0 to 1.0 inclusive).
646     * @param s2 The ending 1st parametric dimension distance to calculate volume for (0.0
647     * to 1.0 inclusive).
648     * @param t2 The ending 2nd parametric dimension distance to calculate volume for (0.0
649     * to 1.0 inclusive).
650     * @param eps The desired fractional accuracy on the enclosed volume.
651     * @return the enclosed volume of a portion of this surface.
652     */
653    public Parameter<Volume> getVolume(double s1, double t1, double s2, double t2, double eps);
654
655    /**
656     * Return the enclosed volume of a portion of this surface.
657     *
658     * @param st1 The starting parametric position to calculate the volume for. Must be a
659     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
660     * @param st2 The ending parametric position to calculate the volume for. Must be a
661     * 2-dimensional point with each value in the range 0 to 1.0. Units are ignored.
662     * @param eps The desired fractional accuracy on the enclosed volume.
663     * @return the enclosed volume of a portion of this surface.
664     */
665    public Parameter<Volume> getVolume(GeomPoint st1, GeomPoint st2, double eps);
666
667    /**
668     * Return an array of SubrangePoint objects that are gridded onto the surface using
669     * the specified spacings and gridding rule.  <code>gridRule</code> specifies whether
670     * the subdivision spacing is applied with respect to arc-length in real space or
671     * parameter space. If the spacing is arc-length, then the values are interpreted as
672     * fractions of the arc length of the edge curves from 0 to 1.
673     *
674     * @param gridRule Specifies whether the subdivision spacing is applied with respect
675     * to arc-length in real space or parameter space.
676     * @param bottomSpacing A list of values used to define the subdivision spacing along
677     * the T=0 parametric boundary of the surface.
678     * @param topSpacing An optional list of values used to define the subdivision spacing
679     * along the T=1 parametric boundary of the surface. If <code>null</code> is passed,
680     * the bottomSpacing is used for the top. If topSpacing is provided, then it must have
681     * the same number of values as the bottomSpacing.
682     * @param leftSpacing A list of values used to define the subdivision spacing along
683     * the S=0 parametric boundary of the surface.
684     * @param rightSpacing An optional list of values used to define the subdivision
685     * spacing along the S=1 parametric boundary of the surface. If <code>null</code> is
686     * passed, the leftSpacing is used for the right. If rightSpacing is provided, then it
687     * must have the same number of values as the leftSpacing.
688     * @return An array of SubrangePoint objects gridded onto the surface at the specified
689     * parametric positions.
690     */
691    public PointArray<SubrangePoint> extractGrid(GridRule gridRule, List<Double> bottomSpacing, List<Double> topSpacing,
692            List<Double> leftSpacing, List<Double> rightSpacing);
693
694    /**
695     * Return an array of points that are gridded onto the surface with the number of
696     * points and spacing chosen to result in straight line segments between the points
697     * that have mid-points that are all within the specified tolerance of this surface.
698     *
699     * @param tol The maximum distance that a straight line between gridded points may
700     * deviate from this surface.
701     * @return An array of subrange points gridded onto the surface.
702     */
703    public PointArray<SubrangePoint> gridToTolerance(Parameter<Length> tol);
704
705    /**
706     * Returns the closest point on this surface to the specified point.
707     *
708     * @param point The point to find the closest point on this surface to.
709     * @param tol Fractional tolerance to refine the distance to.
710     * @return The {@link SubrangePoint} on this surface that is closest to the specified
711     * point.
712     */
713    @Override
714    public SubrangePoint getClosest(GeomPoint point, double tol);
715
716    /**
717     * Returns the closest point on this surface to the specified point near the specified
718     * parametric position.
719     *
720     * @param point The point to find the closest point on this surface to.
721     * @param nearS The parametric s-position where the search for the closest point
722     * should begin.
723     * @param nearT The parametric t-position where the search for the closest point
724     * should begin.
725     * @param tol Fractional tolerance to refine the distance to.
726     * @return The {@link SubrangePoint} on this surface that is closest to the specified
727     * point near the specified parametric position.
728     */
729    public SubrangePoint getClosest(GeomPoint point, double nearS, double nearT, double tol);
730
731    /**
732     * Returns the array of closest points on this surface to the specified array (list of
733     * lists) of points.
734     *
735     * @param points A list of lists of points to find the closest point on this surface to.
736     * @param tol Fractional tolerance to refine the distance to.
737     * @return The {@link PointArray} of {@link SubrangePoint} on this surface that is
738     * closest to the specified list of lists of points.
739     */
740    public PointArray<SubrangePoint> getClosest(List<? extends List<GeomPoint>> points, double tol);
741
742    /**
743     * Returns the farthest point on this surface from the specified point.
744     *
745     * @param point The point to find the farthest point on this surface from.
746     * @param tol Fractional tolerance to refine the distance to.
747     * @return The {@link SubrangePoint} on this surface that is farthest from the
748     * specified point.
749     */
750    @Override
751    public SubrangePoint getFarthest(GeomPoint point, double tol);
752
753    /**
754     * Returns the farthest point on this surface from the specified point near the
755     * specified parametric position on the surface.
756     *
757     * @param point The point to find the farthest point on this surface from.
758     * @param nearS The parametric s-position where the search for the closest point
759     * should begin.
760     * @param nearT The parametric t-position where the search for the closest point
761     * should begin.
762     * @param tol Fractional tolerance to refine the distance to.
763     * @return The {@link SubrangePoint} on this surface that is farthest from the
764     * specified point.
765     */
766    public SubrangePoint getFarthest(GeomPoint point, double nearS, double nearT, double tol);
767
768    /**
769     * Returns the array of farthest points on this surface from the specified array (list
770     * of lists) of points.
771     *
772     * @param points A list of lists of points to find the farthest point on this surface from.
773     * @param tol Fractional tolerance to refine the distance to.
774     * @return The {@link PointArray} of {@link SubrangePoint} on this surface that is
775     * farthest from the specified list of lists of points.
776     */
777    public PointArray<SubrangePoint> getFarthest(List<? extends List<GeomPoint>> points, double tol);
778
779    /**
780     * Returns the closest points (giving the minimum distance) between this surface and
781     * the specified curve. If the specified curve intersects this surface, then the 1st
782     * intersection found is returned (not all the intersections are found and there is no
783     * guarantee about which intersection will be returned). If the specified curve is
784     * parallel to this surface (all points are equidistant away), then any point between
785     * this surface and the specified curve could be returned as the "closest".
786     *
787     * @param curve The curve to find the closest points between this surface and that
788     * curve on.
789     * @param tol Fractional tolerance to refine the distance to.
790     * @return A list containing two SubrangePoint objects that represent the closest
791     * point on this surface (index 0) and the closest point on the specified curve (index
792     * 1).
793     */
794    public PointString<SubrangePoint> getClosest(Curve curve, double tol);
795
796    /**
797     * Returns the closest points (giving the minimum distance) between this surface and
798     * the specified surface. If the specified surface intersects this surface, then the
799     * 1st intersection found is returned (not all the intersections are found and there
800     * is no guarantee about which intersection will be returned). If the specified
801     * surface is parallel to this surface (all points are equidistant away), then any
802     * point between this surface and the specified surface could be returned as the
803     * "closest".
804     *
805     * @param surface The surface to find the closest points between this surface and that
806     * surface on.
807     * @param tol Fractional tolerance to refine the distance to.
808     * @return A list containing two SubrangePoint objects that represent the closest
809     * point on this surface (index 0) and the closest point on the specified surface
810     * (index 1).
811     */
812    public PointString<SubrangePoint> getClosest(Surface surface, double tol);
813
814    /**
815     * Returns the closest point (giving the minimum distance) between this surface and
816     * the specified plane. If the specified plane intersects this surface, then the 1st
817     * intersection found is returned (not all the intersections are found and there is no
818     * guarantee about which intersection will be returned). If the specified plane is
819     * parallel to this surface (all points are equidistant away), then any point between
820     * this surface and the specified plane could be returned as the "closest".
821     *
822     * @param plane The plane to find the closest points between this surface and that
823     * plane on.
824     * @param tol Fractional tolerance to refine the distance to.
825     * @return A SubrangePoint that represent the closest point on this surface to the
826     * specified plane.
827     */
828    public SubrangePoint getClosest(GeomPlane plane, double tol);
829
830    /**
831     * Return <code>true</code> if this surface is degenerate (i.e.: has area less than
832     * the specified tolerance squared).
833     *
834     * @param tol The tolerance for determining if this surface is degenerate.
835     * @return true if this surface is degenerate.
836     */
837    @Override
838    public boolean isDegenerate(Parameter<Length> tol);
839
840    /**
841     * Return <code>true</code> if this surface is planar or <code>false</code> if it is
842     * not.
843     *
844     * @param tol The geometric tolerance to use in determining if the surface is planar.
845     * @return true if this surface is planar.
846     */
847    public boolean isPlanar(Parameter<Length> tol);
848
849    /**
850     * Return <code>true</code> if this surface is planar or <code>false</code> if it is
851     * not.
852     *
853     * @param epsFT Flatness tolerance (cosine of the angle allowable between normal vectors).
854     * @param epsELT Edge linearity tolerance (cosine of the angle allowable between edge
855     * vectors).
856     * @return true if this surface is planar.
857     */
858    public boolean isPlanar(double epsFT, double epsELT);
859
860    /**
861     * Return the intersections between an infinite line and this surface.
862     *
863     * @param L0 A point on the line (origin of the line).
864     * @param Ldir The direction vector for the line (does not have to be a unit vector).
865     * @param tol Tolerance (in physical space) to refine the point positions to.
866     * @return A PointString containing zero or more subrange points made by the
867     * intersection of this surface with the specified infinite line. If no intersection
868     * is found, an empty PointString is returned.
869     */
870    public PointString<SubrangePoint> intersect(GeomPoint L0, GeomVector Ldir, Parameter<Length> tol);
871
872    /**
873     * Return the intersections between a line segment and this surface.
874     *
875     * @param line A line segment to intersect with this surface.
876     * @param tol Tolerance (in physical space) to refine the point positions to.
877     * @return A list containing two PointString instances each containing zero or more
878     * subrange points, on this surface and the input line segment respectively, made by
879     * the intersection of this surface with the specified line segment. If no
880     * intersections are found a list of two empty PointStrings are returned.
881     */
882    public GeomList<PointString<SubrangePoint>> intersect(LineSegment line, Parameter<Length> tol);
883
884    /**
885     * Return the intersections between a curve and this surface.
886     *
887     * @param curve The curve to intersect with this surface.
888     * @param tol Tolerance (in physical space) to refine the point positions to.
889     * @return A list containing two PointString instances each containing zero or more
890     * subrange points, on this surface and the input curve respectively, made by the
891     * intersection of this surface with the specified curve. If no intersections are
892     * found a list of two empty PointStrings are returned.
893     */
894    public GeomList<PointString<SubrangePoint>> intersect(Curve curve, Parameter<Length> tol);
895
896    /**
897     * Return the intersections between an infinite plane and this surface.
898     *
899     * @param plane The infinite plane to intersect with this surface.
900     * @param tol Tolerance (in physical space) to refine the point positions to.
901     * @return A PointString containing zero or more subrange points made by the
902     * intersection of this surface with the specified infinite plane. If no intersection
903     * is found, an empty PointString is returned.
904     */
905    public GeomList<SubrangeCurve> intersect(GeomPlane plane, Parameter<Length> tol);
906
907    /**
908     * Return the intersections between another surface and this surface.
909     *
910     * @param surface A surface to intersect with this surface.
911     * @param tol Tolerance (in physical space) to refine the point positions to.
912     * @return A list containing two lists of SubrangeCurve objects. Each list contains
913     * zero or more subrange curves, on this surface and the input surface respectively,
914     * made by the intersection of this surface with the specified surface. If no
915     * intersections are found a list of two empty lists is returned.
916     */
917    public GeomList<GeomList<SubrangeCurve>> intersect(Surface surface, Parameter<Length> tol);
918
919}