001/**
002 * 
003 */
004package icy.type.geom;
005
006import icy.type.point.Point3D;
007import icy.type.rectangle.Rectangle3D;
008
009/**
010 * This <code>Line3D</code> (3D equivalent to java Line2D class) represents a 3D line segment in {@code (x,y,z)}
011 * coordinate space.
012 * 
013 * @author Stephane
014 */
015public class Line3D implements Shape3D, Cloneable
016{
017    /**
018     * The X coordinate of the start point of the line segment.
019     */
020    protected double x1;
021    /**
022     * The Y coordinate of the start point of the line segment.
023     */
024    protected double y1;
025    /**
026     * The Z coordinate of the start point of the line segment.
027     */
028    protected double z1;
029    /**
030     * The X coordinate of the end point of the line segment.
031     */
032    protected double x2;
033    /**
034     * The Y coordinate of the end point of the line segment.
035     */
036    protected double y2;
037    /**
038     * The Z coordinate of the end point of the line segment.
039     */
040    protected double z2;
041
042    /**
043     * Constructs and initializes a Line with coordinates (0, 0, 0) -> (0, 0, 0).
044     */
045    public Line3D()
046    {
047        super();
048
049        setLine(0d, 0d, 0d, 0d, 0d, 0d);
050    }
051
052    /**
053     * Constructs and initializes a Line from the specified coordinates.
054     * 
055     * @param x1
056     *        the X coordinate of the start point
057     * @param y1
058     *        the Y coordinate of the start point
059     * @param z1
060     *        the Z coordinate of the start point
061     * @param x2
062     *        the X coordinate of the end point
063     * @param y2
064     *        the Y coordinate of the end point
065     * @param z2
066     *        the Z coordinate of the end point
067     */
068    public Line3D(double x1, double y1, double z1, double x2, double y2, double z2)
069    {
070        setLine(x1, y1, z1, x2, y2, z2);
071    }
072
073    /**
074     * Constructs and initializes a <code>Line3D</code> from the specified <code>Point3D</code> objects.
075     * 
076     * @param p1
077     *        the start <code>Point3D</code> of this line segment
078     * @param p2
079     *        the end <code>Point3D</code> of this line segment
080     */
081    public Line3D(Point3D p1, Point3D p2)
082    {
083        setLine(p1, p2);
084    }
085
086    /**
087     * Constructs and initializes a <code>Line3D</code> from the specified <code>Line3D</code> object.
088     * 
089     * @param l
090     *        the <code>Line3D</code> to copy
091     */
092    public Line3D(Line3D l)
093    {
094        setLine(l);
095    }
096
097    /**
098     * Returns the X coordinate of the start point in double precision.
099     * 
100     * @return the X coordinate of the start point of this {@code Line3D} object.
101     */
102    public double getX1()
103    {
104        return x1;
105    }
106
107    /**
108     * Returns the Y coordinate of the start point in double precision.
109     * 
110     * @return the Y coordinate of the start point of this {@code Line3D} object.
111     */
112    public double getY1()
113    {
114        return y1;
115    }
116
117    /**
118     * Returns the Z coordinate of the start point in double precision.
119     * 
120     * @return the Z coordinate of the start point of this {@code Line3D} object.
121     */
122    public double getZ1()
123    {
124        return z1;
125    }
126
127    /**
128     * Returns the start <code>Point3D</code> of this <code>Line3D</code>.
129     * 
130     * @return the start <code>Point3D</code> of this <code>Line3D</code>.
131     */
132    public Point3D getP1()
133    {
134        return new Point3D.Double(getX1(), getY1(), getZ1());
135    }
136
137    /**
138     * Returns the X coordinate of the end point in double precision.
139     * 
140     * @return the X coordinate of the end point of this {@code Line3D} object.
141     */
142    public double getX2()
143    {
144        return x2;
145    }
146
147    /**
148     * Returns the Y coordinate of the end point in double precision.
149     * 
150     * @return the Y coordinate of the end point of this {@code Line3D} object.
151     */
152    public double getY2()
153    {
154        return y2;
155    }
156
157    /**
158     * Returns the Z coordinate of the end point in double precision.
159     * 
160     * @return the Z coordinate of the end point of this {@code Line3D} object.
161     */
162    public double getZ2()
163    {
164        return z2;
165    }
166
167    /**
168     * Returns the end <code>Point3D</code> of this <code>Line3D</code>.
169     * 
170     * @return the end <code>Point3D</code> of this <code>Line3D</code>.
171     */
172    public Point3D getP2()
173    {
174        return new Point3D.Double(getX2(), getY2(), getZ2());
175    }
176
177    /**
178     * Returns the vector representing this <code>Line3D</code>.
179     * 
180     * @return the vector representing this <code>Line3D</code>.
181     */
182    public Point3D getVector()
183    {
184        return new Point3D.Double(getX2() - getX1(), getY2() - getY1(), getZ2() - getZ1());
185    }
186
187    /**
188     * Sets the location of the end points of this <code>Line3D</code> to the specified double coordinates.
189     * 
190     * @param x1
191     *        the X coordinate of the start point
192     * @param y1
193     *        the Y coordinate of the start point
194     * @param z1
195     *        the Z coordinate of the start point
196     * @param x2
197     *        the X coordinate of the end point
198     * @param y2
199     *        the Y coordinate of the end point
200     * @param z2
201     *        the Z coordinate of the start point
202     */
203    public void setLine(double x1, double y1, double z1, double x2, double y2, double z2)
204    {
205        this.x1 = x1;
206        this.y1 = y1;
207        this.z1 = z1;
208        this.x2 = x2;
209        this.y2 = y2;
210        this.z2 = z2;
211    }
212
213    @Override
214    public Rectangle3D getBounds()
215    {
216        double x, y, z;
217        double sizeX, sizeY, sizeZ;
218
219        if (x1 < x2)
220        {
221            x = x1;
222            sizeX = x2 - x1;
223        }
224        else
225        {
226            x = x2;
227            sizeX = x1 - x2;
228        }
229        if (y1 < y2)
230        {
231            y = y1;
232            sizeY = y2 - y1;
233        }
234        else
235        {
236            y = y2;
237            sizeY = y1 - y2;
238        }
239        if (z1 < z2)
240        {
241            z = z1;
242            sizeZ = z2 - z1;
243        }
244        else
245        {
246            z = z2;
247            sizeZ = z1 - z2;
248        }
249
250        return new Rectangle3D.Double(x, y, z, sizeX, sizeY, sizeZ);
251    }
252
253    /**
254     * Sets the location of the end points of this <code>Line3D</code> to
255     * the specified <code>Point3D</code> coordinates.
256     * 
257     * @param p1
258     *        the start <code>Point3D</code> of the line segment
259     * @param p2
260     *        the end <code>Point3D</code> of the line segment
261     */
262    public void setLine(Point3D p1, Point3D p2)
263    {
264        setLine(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ());
265    }
266
267    /**
268     * Sets the location of the end points of this <code>Line3D</code> to
269     * the same as those end points of the specified <code>Line3D</code>.
270     * 
271     * @param l
272     *        the specified <code>Line3D</code>
273     */
274    public void setLine(Line3D l)
275    {
276        setLine(l.getX1(), l.getY1(), l.getZ1(), l.getX2(), l.getY2(), l.getZ2());
277    }
278
279    /**
280     * Tests if the line segment from {@code (x1,y1,z1)} to {@code (x2,y2,z2)} intersects the line segment from
281     * {@code (x3,y3,z3)} to {@code (x4,y4,z4)}.
282     *
283     * @param x1
284     *        the X coordinate of the start point of the first line segment
285     * @param y1
286     *        the Y coordinate of the start point of the first line segment
287     * @param z1
288     *        the Z coordinate of the start point of the first line segment
289     * @param x2
290     *        the X coordinate of the end point of the first line segment
291     * @param y2
292     *        the Y coordinate of the end point of the first line segment
293     * @param z2
294     *        the Z coordinate of the end point of the first line segment
295     * @param x3
296     *        the X coordinate of the start point of the end line segment
297     * @param y3
298     *        the Y coordinate of the start point of the end line segment
299     * @param z3
300     *        the Z coordinate of the start point of the end line segment
301     * @param x4
302     *        the X coordinate of the end point of the end line segment
303     * @param y4
304     *        the Y coordinate of the end point of the end line segment
305     * @param z4
306     *        the Z coordinate of the end point of the end line segment
307     * @return <code>true</code> if the first specified line segment and the second specified line segment intersect
308     *         each other; <code>false</code> otherwise.
309     */
310    public static boolean linesIntersect(double x1, double y1, double z1, double x2, double y2, double z2, double x3,
311            double y3, double z3, double x4, double y4, double z4)
312    {
313        // line 1 vector
314        final Point3D vA = new Point3D.Double(x2 - x1, y2 - y1, z2 - z1);
315        // line 2 vector
316        final Point3D vB = new Point3D.Double(x4 - x3, y4 - y3, z4 - z3);
317        // vector of the 2 starting point
318        final Point3D vC = new Point3D.Double(x3 - x1, y3 - y1, z3 - z1);
319
320        final Point3D crossAB = vA.crossProduct(vB);
321
322        if (vC.dotProduct(crossAB) != 0d) // lines are not coplanar
323            return false;
324
325        final double norm2 = crossAB.norm2();
326        if (norm2 == 0d)
327            return false;
328
329        final Point3D crossCB = vC.crossProduct(vB);
330        final double dot = crossCB.dotProduct(crossAB);
331        final double s = dot / norm2;
332
333        return (s >= 0d) && (s <= 1d);
334    }
335
336    /**
337     * Tests if the line segment from {@code (x1,y1,z1)} to {@code (x2,y2,z2)} intersects this line segment.
338     *
339     * @param x1
340     *        the X coordinate of the start point of the specified line segment
341     * @param y1
342     *        the Y coordinate of the start point of the specified line segment
343     * @param z1
344     *        the Z coordinate of the start point of the specified line segment
345     * @param x2
346     *        the X coordinate of the end point of the specified line segment
347     * @param y2
348     *        the Y coordinate of the end point of the specified line segment
349     * @param z2
350     *        the Z coordinate of the end point of the specified line segment
351     * @return <true> if this line segment and the specified line segment intersect each other; <code>false</code>
352     *         otherwise.
353     */
354    public boolean intersectsLine(double x1, double y1, double z1, double x2, double y2, double z2)
355    {
356        return linesIntersect(x1, y1, z1, x2, y2, z2, getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2());
357    }
358
359    /**
360     * Tests if the specified line segment intersects this line segment.
361     * 
362     * @param l
363     *        the specified <code>Line3D</code>
364     * @return <code>true</code> if this line segment and the specified line
365     *         segment intersect each other; <code>false</code> otherwise.
366     */
367    public boolean intersectsLine(Line3D l)
368    {
369        return linesIntersect(l.getX1(), l.getY1(), l.getZ1(), l.getX2(), l.getY2(), l.getZ2(), getX1(), getY1(),
370                getZ1(), getX2(), getY2(), getZ2());
371    }
372
373    /**
374     * Returns the square of the distance from a point to a line segment.
375     * The distance measured is the distance between the specified point and the closest point between the specified end
376     * points. If the specified point intersects the line segment in between the end points, this method returns 0.0.
377     *
378     * @param x1
379     *        the X coordinate of the start point of the specified line segment
380     * @param y1
381     *        the Y coordinate of the start point of the specified line segment
382     * @param z1
383     *        the Z coordinate of the start point of the specified line segment
384     * @param x2
385     *        the X coordinate of the end point of the specified line segment
386     * @param y2
387     *        the Y coordinate of the end point of the specified line segment
388     * @param z2
389     *        the Z coordinate of the end point of the specified line segment
390     * @param px
391     *        the X coordinate of the specified point being measured against the specified line segment
392     * @param py
393     *        the Y coordinate of the specified point being measured against the specified line segment
394     * @param pz
395     *        the Z coordinate of the specified point being measured against the specified line segment
396     * @return a double value that is the square of the distance from the specified point to the specified line segment.
397     * @see #ptLineDistSq(double,double,double,double, double, double, double, double, double)
398     */
399    public static double ptSegDistSq(double x1, double y1, double z1, double x2, double y2, double z2, double px,
400            double py, double pz)
401    {
402        // Adjust vectors relative to x1,y1,z1
403        // x2,y2,z2 becomes relative vector from x1,y1,z1 to end of segment
404        x2 -= x1;
405        y2 -= y1;
406        z2 -= z1;
407        // px,py,pz becomes relative vector from x1,y1,z1 to test point
408        px -= x1;
409        py -= y1;
410        pz -= z1;
411
412        double dotprod = px * x2 + py * y2 + pz * z2;
413        double projlenSq;
414
415        if (dotprod <= 0.0)
416        {
417            // px,py,pz is on the side of x1,y1,z1 away from x2,y2,z2
418            // distance to segment is length of px,py vector
419            // "length of its (clipped) projection" is now 0.0
420            projlenSq = 0.0;
421        }
422        else
423        {
424            // switch to backwards vectors relative to x2,y2,z2
425            // x2,y2,z2 are already the negative of x1,y1,z1=>x2,y2,z2
426            // to get px,py,pz to be the negative of px,py,pz=>x2,y2,z2
427            // the dot product of two negated vectors is the same
428            // as the dot product of the two normal vectors
429            px = x2 - px;
430            py = y2 - py;
431            pz = z2 - pz;
432            dotprod = px * x2 + py * y2 + pz * z2;
433
434            if (dotprod <= 0.0)
435            {
436                // px,py,pz is on the side of x2,y2,z2 away from x1,y1,z1
437                // distance to segment is length of (backwards) px,py,pz vector
438                // "length of its (clipped) projection" is now 0.0
439                projlenSq = 0.0;
440            }
441            else
442            {
443                // px,py is between x1,y1,z1 and x2,y2,z2
444                // dotprod is the length of the px,py,pz vector
445                // projected on the x2,y2,z2=>x1,y1,z1 vector times the
446                // length of the x2,y2,z2=>x1,y1,z1 vector
447                projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2 + z2 * z2);
448            }
449        }
450
451        // Distance to line is now the length of the relative point
452        // vector minus the length of its projection onto the line
453        // (which is zero if the projection falls outside the range
454        // of the line segment).
455        double lenSq = px * px + py * py + pz * pz - projlenSq;
456        if (lenSq < 0)
457            lenSq = 0;
458
459        return lenSq;
460    }
461
462    /**
463     * Returns the distance from a point to a line segment.
464     * The distance measured is the distance between the specified point and the closest point between the specified end
465     * points. If the specified point intersects the line segment in between the end points, this method returns 0.0.
466     *
467     * @param x1
468     *        the X coordinate of the start point of the specified line segment
469     * @param y1
470     *        the Y coordinate of the start point of the specified line segment
471     * @param z1
472     *        the Z coordinate of the start point of the specified line segment
473     * @param x2
474     *        the X coordinate of the end point of the specified line segment
475     * @param y2
476     *        the Y coordinate of the end point of the specified line segment
477     * @param z2
478     *        the Z coordinate of the end point of the specified line segment
479     * @param px
480     *        the X coordinate of the specified point being measured against the specified line segment
481     * @param py
482     *        the Y coordinate of the specified point being measured against the specified line segment
483     * @param pz
484     *        the Z coordinate of the specified point being measured against the specified line segment
485     * @return a double value that is the distance from the specified point to the specified line segment.
486     * @see #ptLineDist(double, double, double, double,double, double, double, double, double)
487     */
488    public static double ptSegDist(double x1, double y1, double z1, double x2, double y2, double z2, double px,
489            double py, double pz)
490    {
491        return Math.sqrt(ptSegDistSq(x1, y1, z1, x2, y2, z2, px, py, pz));
492    }
493
494    /**
495     * Returns the square of the distance from a point to this line segment.
496     * The distance measured is the distance between the specified point and the closest point between the current
497     * line's end points. If the specified point intersects the line segment in between the end points, this method
498     * returns 0.0.
499     *
500     * @param px
501     *        the X coordinate of the specified point being measured against this line segment
502     * @param py
503     *        the Y coordinate of the specified point being measured against this line segment
504     * @param pz
505     *        the Z coordinate of the specified point being measured against this line segment
506     * @return a double value that is the square of the distance from the specified point to the current line segment.
507     * @see #ptLineDistSq(double, double,double)
508     */
509    public double ptSegDistSq(double px, double py, double pz)
510    {
511        return ptSegDistSq(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), px, py, pz);
512    }
513
514    /**
515     * Returns the square of the distance from a <code>Point3D</code> to this line segment.
516     * The distance measured is the distance between the specified point and the closest point between the current
517     * line's end points. If the specified point intersects the line segment in between the end points, this method
518     * returns 0.0.
519     * 
520     * @param pt
521     *        the specified <code>Point3D</code> being measured against this line segment.
522     * @return a double value that is the square of the distance from the specified <code>Point3D</code> to the current
523     *         line segment.
524     * @see #ptLineDistSq(Point3D)
525     */
526    public double ptSegDistSq(Point3D pt)
527    {
528        return ptSegDistSq(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), pt.getX(), pt.getY(), pt.getZ());
529    }
530
531    /**
532     * Returns the distance from a point to this line segment.
533     * The distance measured is the distance between the specified point and the closest point between the current
534     * line's end points. If the specified point intersects the line segment in between the end points, this method
535     * returns 0.0.
536     *
537     * @param px
538     *        the X coordinate of the specified point being measured against this line segment
539     * @param py
540     *        the Y coordinate of the specified point being measured against this line segment
541     * @param pz
542     *        the Z coordinate of the specified point being measured against this line segment
543     * @return a double value that is the distance from the specified point to the current line segment.
544     * @see #ptLineDist(double, double, double)
545     */
546    public double ptSegDist(double px, double py, double pz)
547    {
548        return ptSegDist(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), px, py, pz);
549    }
550
551    /**
552     * Returns the distance from a <code>Point3D</code> to this line segment.
553     * The distance measured is the distance between the specified point and the closest point between the current
554     * line's end points. If the specified point intersects the line segment in between the end points, this method
555     * returns 0.0.
556     * 
557     * @param pt
558     *        the specified <code>Point3D</code> being measured against this line segment
559     * @return a double value that is the distance from the specified <code>Point3D</code> to the current line segment.
560     * @see #ptLineDist(Point3D)
561     */
562    public double ptSegDist(Point3D pt)
563    {
564        return ptSegDist(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), pt.getX(), pt.getY(), pt.getZ());
565    }
566
567    /**
568     * Returns the square of the distance from a point to a line.
569     * The distance measured is the distance between the specified point and the closest point on the
570     * infinitely-extended line defined by the specified coordinates. If the specified point intersects the line, this
571     * method returns 0.0.
572     *
573     * @param x1
574     *        the X coordinate of the start point of the specified line
575     * @param y1
576     *        the Y coordinate of the start point of the specified line
577     * @param z1
578     *        the Z coordinate of the start point of the specified line
579     * @param x2
580     *        the X coordinate of the end point of the specified line
581     * @param y2
582     *        the Y coordinate of the end point of the specified line
583     * @param z2
584     *        the Z coordinate of the end point of the specified line
585     * @param px
586     *        the X coordinate of the specified point being measured against the specified line
587     * @param py
588     *        the Y coordinate of the specified point being measured against the specified line
589     * @param pz
590     *        the Z coordinate of the specified point being measured against the specified line
591     * @return a double value that is the square of the distance from the specified point to the specified line.
592     * @see #ptSegDistSq(double, double, double, double,double, double, double, double, double)
593     */
594    public static double ptLineDistSq(double x1, double y1, double z1, double x2, double y2, double z2, double px,
595            double py, double pz)
596    {
597        // Adjust vectors relative to x1,y1,z1
598        // x2,y2 becomes relative vector from x1,y1,z1 to end of segment
599        x2 -= x1;
600        y2 -= y1;
601        z2 -= z1;
602        // px,py,pz becomes relative vector from x1,y1,z1 to test point
603        px -= x1;
604        py -= y1;
605        pz -= z1;
606
607        double dotprod = px * x2 + py * y2 + pz * z2;
608        // dotprod is the length of the px,py vector
609        // projected on the x1,y1,z1=>x2,y2,z2 vector times the
610        // length of the x1,y1,z1=>x2,y2,z2 vector
611        double projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2 + z2 * z2);
612        // Distance to line is now the length of the relative point
613        // vector minus the length of its projection onto the line
614        double lenSq = px * px + py * py + pz * pz - projlenSq;
615
616        if (lenSq < 0)
617            lenSq = 0;
618
619        return lenSq;
620    }
621
622    /**
623     * Returns the distance from a point to a line.
624     * The distance measured is the distance between the specified point and the closest point on the
625     * infinitely-extended line defined by the specified coordinates. If the specified point intersects the line, this
626     * method returns 0.0.
627     *
628     * @param x1
629     *        the X coordinate of the start point of the specified line
630     * @param y1
631     *        the Y coordinate of the start point of the specified line
632     * @param z1
633     *        the Z coordinate of the start point of the specified line
634     * @param x2
635     *        the X coordinate of the end point of the specified line
636     * @param y2
637     *        the Y coordinate of the end point of the specified line
638     * @param z2
639     *        the Z coordinate of the end point of the specified line
640     * @param px
641     *        the X coordinate of the specified point being measured against the specified line
642     * @param py
643     *        the Y coordinate of the specified point being measured against the specified line
644     * @param pz
645     *        the Z coordinate of the specified point being measured against the specified line
646     * @return a double value that is the distance from the specified point to the specified line.
647     * @see #ptSegDist(double, double, double, double, double, double, double, double, double)
648     */
649    public static double ptLineDist(double x1, double y1, double z1, double x2, double y2, double z2, double px,
650            double py, double pz)
651    {
652        return Math.sqrt(ptLineDistSq(x1, y1, z1, x2, y2, z2, px, py, pz));
653    }
654
655    /**
656     * Returns the square of the distance from a point to this line.
657     * The distance measured is the distance between the specified point and the closest point on the
658     * infinitely-extended line defined by this <code>Line3D</code>. If the specified point intersects the line, this
659     * method returns 0.0.
660     *
661     * @param px
662     *        the X coordinate of the specified point being measured against the specified line
663     * @param py
664     *        the Y coordinate of the specified point being measured against the specified line
665     * @param pz
666     *        the Z coordinate of the specified point being measured against the specified line
667     * @return a double value that is the square of the distance from a specified point to the current line.
668     * @see #ptSegDistSq(double, double, double)
669     */
670    public double ptLineDistSq(double px, double py, double pz)
671    {
672        return ptLineDistSq(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), px, py, pz);
673    }
674
675    /**
676     * Returns the square of the distance from a specified <code>Point3D</code> to this line.
677     * The distance measured is the distance between the specified point and the closest point on the
678     * infinitely-extended line defined by this <code>Line3D</code>. If the specified point intersects the line, this
679     * method returns 0.0.
680     * 
681     * @param pt
682     *        the specified <code>Point3D</code> being measured against this line
683     * @return a double value that is the square of the distance from a specified <code>Point3D</code> to the current
684     *         line.
685     * @see #ptSegDistSq(Point3D)
686     */
687    public double ptLineDistSq(Point3D pt)
688    {
689        return ptLineDistSq(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), pt.getX(), pt.getY(), pt.getZ());
690    }
691
692    /**
693     * Returns the distance from a point to this line.
694     * The distance measured is the distance between the specified point and the closest point on the
695     * infinitely-extended line defined by this <code>Line3D</code>. If the specified point intersects the line, this
696     * method returns 0.0.
697     *
698     * @param px
699     *        the X coordinate of the specified point being measured against this line
700     * @param py
701     *        the Y coordinate of the specified point being measured against this line
702     * @param pz
703     *        the Z coordinate of the specified point being measured against this line
704     * @return a double value that is the distance from a specified point to the current line.
705     * @see #ptSegDist(double, double, double)
706     */
707    public double ptLineDist(double px, double py, double pz)
708    {
709        return ptLineDist(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), px, py, pz);
710    }
711
712    /**
713     * Returns the distance from a <code>Point3D</code> to this line.
714     * The distance measured is the distance between the specified point and the closest point on the
715     * infinitely-extended line defined by this <code>Line3D</code>. If the specified point intersects the line, this
716     * method returns 0.0.
717     * 
718     * @param pt
719     *        the specified <code>Point3D</code> being measured
720     * @return a double value that is the distance from a specified <code>Point3D</code> to the current line.
721     * @see #ptSegDist(Point3D)
722     */
723    public double ptLineDist(Point3D pt)
724    {
725        return ptLineDist(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2(), pt.getX(), pt.getY(), pt.getZ());
726    }
727
728    /**
729     * Tests if a specified coordinate is inside the boundary of this <code>Line3D</code>. This method is required to
730     * implement the {@link Shape3D} interface, but in the case of <code>Line3D</code> objects it always returns
731     * <code>false</code> since a line contains no area.
732     * 
733     * @param x
734     *        the X coordinate of the specified point to be tested
735     * @param y
736     *        the Y coordinate of the specified point to be tested
737     * @param z
738     *        the Z coordinate of the specified point to be tested
739     * @return <code>false</code> because a <code>Line3D</code> contains no area.
740     */
741    @Override
742    public boolean contains(double x, double y, double z)
743    {
744        return false;
745    }
746
747    /**
748     * Tests if a given <code>Point3D</code> is inside the boundary of this <code>Line3D</code>.
749     * This method is required to implement the {@link Shape3D} interface, but in the case of <code>Line3D</code>
750     * objects it always returns <code>false</code> since a line contains no area.
751     * 
752     * @param p
753     *        the specified <code>Point3D</code> to be tested
754     * @return <code>false</code> because a <code>Line3D</code> contains no area.
755     */
756    @Override
757    public boolean contains(Point3D p)
758    {
759        return false;
760    }
761
762    /**
763     * Tests if the interior of this <code>Line3D</code> entirely contains the specified set of rectangular coordinates.
764     * This method is required to implement the <code>Shape3D</code> interface, but in the case of <code>Line3D</code>
765     * objects it always returns false since a line contains no area.
766     * 
767     * @param x
768     *        the X coordinate of the closest-upper-left corner of the specified 3D rectangular area
769     * @param y
770     *        the Y coordinate of the closest-upper-left corner of the specified 3D rectangular area
771     * @param z
772     *        the Z coordinate of the closest-upper-left corner of the specified 3D rectangular area
773     * @param sizeX
774     *        the width of the specified 3D rectangular area
775     * @param sizeY
776     *        the height of the specified 3D rectangular area
777     * @param sizeZ
778     *        the depth of the specified 3D rectangular area
779     * @return <code>false</code> because a <code>Line3D</code> contains
780     *         no area.
781     */
782    @Override
783    public boolean contains(double x, double y, double z, double sizeX, double sizeY, double sizeZ)
784    {
785        return false;
786    }
787
788    /**
789     * Tests if the interior of this <code>Line3D</code> entirely contains the specified <code>Rectangle3D</code>.
790     * This method is required to implement the <code>Shape3D</code> interface, but in the case of <code>Line3D</code>
791     * objects it always returns <code>false</code> since a line contains no area.
792     * 
793     * @param r
794     *        the specified <code>Rectangle3D</code> to be tested
795     * @return <code>false</code> because a <code>Line3D</code> contains no area.
796     */
797    @Override
798    public boolean contains(Rectangle3D r)
799    {
800        return false;
801    }
802
803    @Override
804    public boolean intersects(double x, double y, double z, double sizeX, double sizeY, double sizeZ)
805    {
806        return intersects(new Rectangle3D.Double(x, y, z, sizeX, sizeY, sizeZ));
807    }
808
809    @Override
810    public boolean intersects(Rectangle3D r)
811    {
812        return r.intersectsLine(getX1(), getY1(), getZ1(), getX2(), getY2(), getZ2());
813    }
814
815    /**
816     * Creates a new object of the same class as this object.
817     *
818     * @return a clone of this instance.
819     * @exception OutOfMemoryError
820     *            if there is not enough memory.
821     * @see java.lang.Cloneable
822     */
823    @Override
824    public Object clone()
825    {
826        try
827        {
828            return super.clone();
829        }
830        catch (CloneNotSupportedException e)
831        {
832            // this shouldn't happen, since we are Cloneable
833            throw new InternalError();
834        }
835    }
836}