All Downloads are FREE. Search and download functionalities are using the official Maven repository.

darwin.util.math.base.Line Maven / Gradle / Ivy

/*
 * Copyright (C) 2012 daniel
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a clone of the GNU General Public License
 * along with this program.  If not, see .
 */
package darwin.util.math.base;

import darwin.util.math.base.vector.*;

/**
 *
 ** @author Daniel Heinrich 
 */
//TODO get rid of all the toVector3 converts and the using of cross products
public final class Line> {

    public enum Relationship {

        EQUAL, PARALLEL,
        SKEW, //Windschief
        INTERSECTING
    }
    private final ImmutableVector a;
    private final ImmutableVector dir;

    public Line(ImmutableVector a, ImmutableVector dir) {
        if (dir.lengthQuad() == 0.) {
            throw new IllegalArgumentException("The direction vector must not have a length of zero!");
        }
        this.a = a.clone();
        this.dir = dir.clone().normalize();
    }

    public static > Line fromPoints(ImmutableVector a,
                                                           ImmutableVector b) {
        return new Line<>(a, a.clone().sub(b));
    }

    public Relationship getRelationship(Line g) {
        if (isParallelTo(g)) {
            if (contains(g.a)) {
                return Relationship.EQUAL;
            } else {
                return Relationship.PARALLEL;
            }
        } else if (isSkewTo(g)) {
            return Relationship.SKEW;
        } else {
            return Relationship.INTERSECTING;
        }
    }

    public boolean isParallelTo(Line g) {
        return g.dir.isParrallelTo(dir);
    }

    public boolean isEqualTo(Line g) {
        return isParallelTo(g) && contains(g.a);
    }

    public boolean intersectsWith(Line g) {
        return !isSkewTo(g);
    }

    public boolean isSkewTo(Line g) {
        ImmutableVector tmp = a.clone().sub(g.a).toVector3();
        return !tmp.clone().cross(dir.toVector3()).isParrallelTo(tmp.clone().cross(g.dir.toVector3()));
    }

    public boolean contains(ImmutableVector p) {
        return p.clone().sub(a).isParrallelTo(dir);
    }

    public E getIntersection(Line g) {
        float[] d = dir.getCoords();
        if (d.length < 2) {
            throw new IllegalArgumentException("Can not intersect one dimesional Vectors!");
        }
        float[] t = g.dir.getCoords();
        float[] c = g.a.clone().sub(a).getCoords();

        int a = -1, b = -1;
        out:
        for (int i = 0; i < d.length; i++) {
            if (d[i] != 0) {
                a = i;
                for (int j = 0; j < t.length; j++) {
                    if (j == i) {
                        continue;
                    }
                    if (t[j] != 0) {
                        b = j;
                        break out;
                    }
                }
            }
        }
        
        if(a==-1 || b==-1)
        {
            throw new IllegalArgumentException("The two lines do not intersect!");
        }

        float x2 = (c[a] * d[b] / (d[a] * t[b]) - c[b] / t[b]) / (1 - t[a] * d[b] / (d[a] * t[b]));
        return g.getPoint(x2);
    }

    public double distanceToSquared(ImmutableVector p) {
        Vector tmp = a.clone().sub(p);
        return tmp.lengthQuad() - dir.dot(tmp);
    }

    public double distanceTo(ImmutableVector p) {
        return Math.sqrt(distanceToSquared(p));
    }

    public double distanceTo(Line g) {
        if (isParallelTo(g)) {
            return distanceTo(g.a);
        } else {
            //TODO
            Vector3 n = dir.toVector3().cross(g.dir.toVector3()).normalize();
            return Math.abs(a.clone().sub(g.a).toVector3().dot(n));
        }
    }

    public ImmutableVector getStartingPoint() {
        return a;
    }

    public ImmutableVector getDirection() {
        return dir;
    }

    public E getPoint(float lerp) {
        return dir.clone().mul(lerp).add(a);
    }

    public boolean isElement(ImmutableVector point) {
        return point.clone().sub(getStartingPoint()).isParrallelTo(getDirection());
    }

    @Override
    public String toString() {
        return "Aufpunkt: " + a + "\nRichtung: " + dir;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Line other = (Line) obj;

        return isEqualTo(other);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        return hash;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy