line.java

来自「world wind java sdk 源码」· Java 代码 · 共 256 行

JAVA
256
字号
/*Copyright (C) 2001, 2006 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.geom;import gov.nasa.worldwind.util.Logging;/** * @author Tom Gaskins * @version $Id: Line.java 3209 2007-10-06 21:57:53Z tgaskins $ */public final class Line// Instances are immutable{    private final Vec4 origin;    private final Vec4 direction;    /**     * Create the line containing a line segement between two points.     *     * @param pa the first point of the line segment.     * @param pb the second point of the line segment.     * @return The line containing the two points.     * @throws IllegalArgumentException if either point is null or they are coincident.     */    public static Line fromSegment(Vec4 pa, Vec4 pb)    {        return new Line(pa, new Vec4(pb.x - pa.x, pb.y - pa.y, pb.z - pa.z, 0));    }    /**     * @param origin     * @param direction     * @throws IllegalArgumentException if <code>origin</code> is null, or <code>direction</code> is null or has zero     *                                  length     */    public Line(Vec4 origin, Vec4 direction)    {        String message = null;        if (origin == null)            message = "nullValue.OriginIsNull";        else if (direction == null)            message = "nullValue.DirectionIsNull";        else if (direction.getLength3() <= 0)            message = "Geom.Line.DirectionIsZeroVector";        if (message != null)        {            message = Logging.getMessage(message);            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        this.origin = origin;        this.direction = direction;    }    public final Vec4 getDirection()    {        return direction;    }    public final Vec4 getOrigin()    {        return origin;    }    public final Vec4 getPointAt(double t)    {        return Vec4.fromLine3(this.origin, t, this.direction);    }    public final double selfDot()    {        return this.origin.dot3(this.direction);    }    /**     * Performs a comparison to test whether this Object is internally identical to the other Object <code>o</code>.     * This method takes into account both direction and origin, so two lines which may be equivalent may not be     * considered equal.     *     * @param o the object to be compared against.     * @return true if these two objects are equal, false otherwise     */    @Override    public final boolean equals(Object o)    {        if (this == o)            return true;        if (o == null || getClass() != o.getClass())            return false;        final gov.nasa.worldwind.geom.Line line = (gov.nasa.worldwind.geom.Line) o;        if (!direction.equals(line.direction))            return false;        //noinspection RedundantIfStatement        if (!line.origin.equals(origin))            return false;        return true;    }    @Override    public final int hashCode()    {        int result;        result = origin.hashCode();        result = 29 * result + direction.hashCode();        return result;    }    public String toString()    {        return "Origin: " + this.origin + ", Direction: " + this.direction;    }////    public final double distanceToOld(Vec4 p)//    {//        if (p == null)//        {//            String message = Logging.getMessage("nullValue.PointIsNull");//            Logging.logger().severe(message);//            throw new IllegalArgumentException(message);//        }////        Vec4 origin = this.origin;//        Vec4 sideB = origin.subtract3(p); // really a vector////        double distanceToOrigin = sideB.dot3(this.direction);//        double divisor = distanceToOrigin / this.direction.getLengthSquared3();////        Vec4 sideA = this.direction.multiply3(divisor);////        double aSquared = sideA.getLengthSquared3();//        double bSquared = sideB.getLengthSquared3();////        return Math.sqrt(bSquared - aSquared);//    }    public final Vec4 nearestPointTo(Vec4 p)    {        Vec4 w = p.subtract3(this.origin);        double c1 = w.dot3(this.direction);        double c2 = this.direction.dot3(this.direction);        return this.origin.add3(this.direction.multiply3(c1 / c2));    }    /**     * Calculate the shortests distance between this line and a specified <code>Vec4</code>. This method returns a     * positive distance.     *     * @param p the <code>Vec4</code> whose distance from this <code>Line</code> will be calculated     * @return the distance between this <code>Line</code> and the specified <code>Vec4</code>     * @throws IllegalArgumentException if <code>p</code> is null     */    public final double distanceTo(Vec4 p)    {        return p.distanceTo3(this.nearestPointTo(p));    }    public static Vec4 nearestPointOnSegment(Vec4 p0, Vec4 p1, Vec4 p)    {        Vec4 v = p1.subtract3(p0);        Vec4 w = p.subtract3(p0);        double c1 = w.dot3(v);        double c2 = v.dot3(v);        if (c1 <= 0)            return p0;        if (c2 <= c1)            return p1;        return p0.add3(v.multiply3(c1 / c2));    }    public static double distanceToSegment(Vec4 p0, Vec4 p1, Vec4 p)    {        Vec4 pb = nearestPointOnSegment(p0, p1, p);        return p.distanceTo3(pb);    }    /**     * Clip a line segment to a frustum, returning the end points of the portion of the segment that is within the     * frustum.     *     * @param pa      the first point of the segment.     * @param pb      the second point of the segment.     * @param frustum the frustum.     * @return The two points at which the segment intersects the frustum, or null if the segment does not intersect and     *         the frustum does not fully contain it. If the segment is coincident with a plane of the frustum, the     *         returned segment is the portion of the original segment on that plane, clipped to the other frustum     *         planes.     */    public static Vec4[] clipToFrustum(Vec4 pa, Vec4 pb, Frustum frustum)    {        return clipToFrustum(pa, pb, frustum, 1);    }    private static Vec4[] clipToFrustum(Vec4 pa, Vec4 pb, Frustum frustum, int maxRecursionCount)    {        if (pa == null || pb == null)        {            String message = Logging.getMessage("nullValue.PointIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        if (frustum == null)        {            String message = Logging.getMessage("nullValue.FrustumIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        // First do a trivial accept test.        if (frustum.contains(pa) && frustum.contains(pb))            return new Vec4[] {pa, pb};        Vec4[] segment = new Vec4[] {pa, pb};        Vec4[] ipts;        for (Plane p : frustum.getAllPlanes())        {            // See if both points are behind the plane and therefore not in the frustum.            if (p.onSameSide(segment[0], segment[1]) < 0)                return null;            // Clip the segment to the plane if they intersect.            ipts = p.clip(segment[0], segment[1]);            if (ipts != null)            {                segment = ipts;            }        }        // If one of the initial points was in the frustum then the segment must have been clipped.        if (frustum.contains(pa) || frustum.contains(pb))            return segment;        // The segment was clipped by an infinite frustum plane but may still lie outside the frustum.        // So recurse using the clipped segment.        if (maxRecursionCount > 0)            return clipToFrustum(segment[0], segment[1], frustum, --maxRecursionCount);        else            return segment;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?