Search in sources :

Example 11 with Line

use of org.apache.commons.math3.geometry.euclidean.twod.Line in project chordatlas by twak.

the class FindLines method regress.

private Line regress(Set<Line> things, LinearForm lfDir) {
    SimpleRegression fit = new SimpleRegression();
    // regression isn't happy on lines with infinite slope: so swap params!
    boolean flip = Math.abs(lfDir.x) > Math.abs(lfDir.y);
    for (Line l : things) if (flip) {
        fit.addData(l.start.y, l.start.x);
        fit.addData(l.end.y, l.end.x);
    } else {
        fit.addData(l.start.x, l.start.y);
        fit.addData(l.end.x, l.end.y);
    }
    double intercept = fit.getIntercept(), slope = fit.getSlope();
    if (Double.isNaN(intercept))
        return null;
    LinearForm lf;
    if (flip)
        lf = new LinearForm(1, -slope);
    else
        lf = new LinearForm(-slope, 1);
    if (lf.unitVector().angle(lfDir.unitVector()) > Math.PI / 2) {
        // if regression is pointing wrong way, flip
        lf.x = -lf.x;
        lf.y = -lf.y;
    }
    if (flip)
        lf.findC(intercept, 0);
    else
        lf.findC(0, intercept);
    double[] minMax = things.stream().map(x -> new double[] { lf.findPParam(x.start), lf.findPParam(x.end) }).collect(new InAxDoubleArray());
    // do regression
    return new Line(lf, minMax[0], minMax[1]);
}
Also used : Line(org.twak.utils.Line) Iterator(java.util.Iterator) Line(org.twak.utils.Line) Set(java.util.Set) MultiMapSet(org.twak.utils.collections.MultiMapSet) HashMap(java.util.HashMap) Vector2d(javax.vecmath.Vector2d) Pair(org.twak.utils.Pair) LinearForm(org.twak.utils.geom.LinearForm) ConsecutiveItPairs(org.twak.utils.collections.ConsecutiveItPairs) ArrayList(java.util.ArrayList) Point2d(javax.vecmath.Point2d) List(java.util.List) SimpleRegression(org.apache.commons.math3.stat.regression.SimpleRegression) Map(java.util.Map) Anglez(org.twak.utils.geom.Anglez) InAxDoubleArray(org.twak.utils.streams.InAxDoubleArray) Result(org.twak.viewTrace.RangeMerge.Result) InAxDoubleArray(org.twak.utils.streams.InAxDoubleArray) SimpleRegression(org.apache.commons.math3.stat.regression.SimpleRegression) LinearForm(org.twak.utils.geom.LinearForm)

Example 12 with Line

use of org.apache.commons.math3.geometry.euclidean.twod.Line in project chordatlas by twak.

the class Prof method parameterize.

public static // all profs from a single profile-edge are in the same 2D space, with strange x-origin
Prof parameterize(// all profs from a single profile-edge are in the same 2D space, with strange x-origin
List<Prof> in) {
    // double toProfileEdge;
    // {
    // Prof eg = in.iterator().next();
    // Point3d p = Pointz.to3( profileEdge.start );
    // toProfileEdge = eg.to2d( p ).x;
    // }
    double avgMinY = in.stream().filter(p -> p != null).mapToDouble(p -> p.get(0).y).average().getAsDouble();
    Set<Line> lines = new HashSet<>();
    for (Prof p : in) for (int i = 1; i < p.size(); i++) lines.add(new Line(p.get(i - 1), p.get(i)));
    SliceParameters P = new SliceParameters(5);
    P.FL_REGRESS = true;
    P.FL_BINS = 20;
    // double A = 0.4; // simple = 0.4
    // double B = 0.1; // simple = 1;
    // simple = 0.4
    double A = 0.2;
    // simple = 0.1;
    double B = 0.3;
    // simple = 0.1; rotate threshold, radians
    double C = 0.1;
    double firstFloorHeight = 2;
    P.MIN_LINES = Math.max(1, in.size() * A);
    lines = new FindLines(lines, P) {

        protected double nextAngle(Set<Line> remaining, int iteration) {
            double delta = Math.PI / P.FL_BINS;
            // angle bin
            Bin<Line> aBin = new Bin(-Math.PI - delta, Math.PI + delta, P.FL_BINS * 2, true);
            for (Line l : remaining) {
                double len = l.length();
                double angle = l.aTan2();
                aBin.add(angle, len, l);
            }
            // return MUtils.PI2;
            if (iteration < 1 && aBin.getWeight(Mathz.PI2) >= 10)
                return Mathz.PI2;
            int aBinI = aBin.maxI();
            return aBin.val(aBinI);
        }

        protected double getTolNearLine(Point2d p) {
            return P.FL_NEAR_LINE * (p.y < avgMinY + firstFloorHeight ? 5 : B);
        }

        protected double getTolNearLine2(Point2d p) {
            return P.FL_NEAR_LINE_2 * (p.y < avgMinY + firstFloorHeight ? 10 : B);
        }

        protected double getTolRemoveAngle(Line l) {
            return l.start.y < avgMinY + firstFloorHeight ? Math.PI * 0.5 : Math.PI * 0.2;
        }
    }.result.all;
    List<Line> llines = // is rubbish
    lines.stream().filter(l -> l.lengthSquared() > 0.001).filter(// is floor polygon
    l -> l.end.y > avgMinY + 1 || Math.abs(l.start.y - l.end.y) > 0.1).collect(Collectors.toList());
    Prof clean = new Prof(in.get(in.size() / 2));
    clean.clear();
    if (llines.isEmpty()) {
        clean.add(new Point2d(0, 0));
        clean.add(new Point2d(0, 1));
        return clean;
    }
    for (int i = 0; i < llines.size(); i++) {
        Line l = llines.get(i);
        double angle = l.aTan2();
        if (angle < Mathz.PI2 + C && angle > Mathz.PI2 - C)
            llines.set(i, FindLines.rotateToAngle(l, l.fromPPram(0.5), Mathz.PI2));
    }
    // llines.stream().filter( l -> l.start.y > l.end.y ).forEach( l -> l.reverseLocal() );
    Collections.sort(llines, new Comparator<Line>() {

        public int compare(Line o1, Line o2) {
            return Double.compare(o1.fromPPram(0.2).y, o2.fromPPram(0.2).y);
        }
    });
    // for (Line l : llines)
    // PaintThing.debug( new Color(170,0,255), 2f, new Line( l.start.x+5, -l.start.y, l.end.x+5, -l.end.y ) );
    Line lastL = null;
    Point2d lastP = new Point2d(0, -Double.MAX_VALUE);
    for (Line l : llines) {
        // if (c >= 6)
        // continue;
        // if ( c== 5)
        // System.out.println("here");
        // c++;
        Point2d mid = l.fromPPram(0.5);
        if (!(lastL != null && !lastL.isOnLeft(mid) || (lastP.y == -Double.MAX_VALUE || (mid.y >= lastP.y - 0.5 && mid.x <= lastP.x + 0.5))))
            continue;
        boolean startAbove = l.start.y >= lastP.y && l.start.x <= lastP.x, endAbove = l.end.y >= lastP.y && l.end.x <= lastP.x;
        if (l.end.y < l.start.y)
            l.end.y = l.start.y;
        if (startAbove && endAbove) {
        // okay
        } else {
            if (lastL != null && l.start.distanceSquared(lastP) < 9) {
                Point2d sec = lastL.intersects(l, false);
                if (sec != null && sec.distanceSquared(lastP) < 9 && sec.x <= lastL.start.x && sec.y >= lastL.start.y) {
                    clean.remove(clean.size() - 1);
                    clean.add(sec);
                    lastP = sec;
                    l.start = sec;
                } else if (l.start.x < lastP.x) {
                    sec = new LinearForm(new Vector2d(1, 0)).findC(l.start).intersect(new LinearForm(lastL));
                    if (sec != null && sec.distanceSquared(lastP) < 9) {
                        clean.remove(clean.size() - 1);
                        clean.add(sec);
                        lastP = sec;
                    }
                }
            }
            if (l.start.x > lastP.x + 0.01 || l.end.x > lastP.x + 0.01) {
                Point2d sec = new LinearForm(new Vector2d(0, 1)).findC(new Point2d(lastP.x, 0)).intersect(new LinearForm(l));
                if (sec != null && sec.distanceSquared(lastP) < 9 && sec.distanceSquared(l.start) < 9) {
                    if (l.start.x > lastP.x)
                        l.start = sec;
                    else
                        l.end = sec;
                }
            }
        }
        if (lastL != null && l.start.distanceSquared(lastP) < 4) {
            Point2d sec = lastL.intersects(l, false);
            if (sec != null && (sec.distanceSquared(lastP) < 4 || Math.abs(sec.y - lastP.y) < 1) && sec.x <= lastL.start.x && sec.y >= lastL.start.y) {
                clean.remove(clean.size() - 1);
                clean.add(sec);
                lastP = sec;
                l.start = sec;
            } else if (l.start.x < lastP.x) {
                sec = new LinearForm(new Vector2d(1, 0)).findC(l.start).intersect(new LinearForm(lastL));
                if (sec != null && (sec.distanceSquared(lastP) < 4 || Math.abs(sec.y - lastP.y) < 1)) {
                    clean.remove(clean.size() - 1);
                    clean.add(sec);
                    lastP = sec;
                // l.start = sec;
                }
            }
        }
        if (lastP.y - l.end.y < 3 && l.end.x - lastP.x < 3) {
            for (Point2d pt : l.points()) {
                pt.x = Math.min(pt.x, lastP.x);
                pt.y = Math.max(pt.y, lastP.y);
            }
            if (!l.start.equals(l.end))
                for (Point2d pt : l.points()) {
                    // if (c == 2)
                    // PaintThing.debug.put(1, new Point2d ( pt.x, -pt.y ) );
                    pt = new Point2d(pt);
                    pt.x = Math.min(pt.x, lastP.x);
                    pt.y = Mathz.max(0, pt.y, lastP.y);
                    if (clean.isEmpty() && pt.y > 0.2) {
                        clean.add(new Point2d(pt.x, 0));
                    }
                    if (lastP != null && pt.distanceSquared(lastP) > 0.02) {
                        clean.add(pt);
                    }
                    lastP = clean.get(clean.size() - 1);
                    if (clean.size() >= 3) {
                        Point2d a = clean.get(clean.size() - 1), b = clean.get(clean.size() - 2), c = clean.get(clean.size() - 3);
                        if (Math.abs(Mathz.area(c, b, a)) < 0.1 || Mathz.absAngleBetween(a, b, c) < 0.1)
                            clean.remove(clean.size() - 2);
                    }
                }
        }
        if (clean.size() >= 2)
            lastL = new Line(clean.get(clean.size() - 2), clean.get(clean.size() - 1));
    }
    return clean;
}
Also used : ConsecutivePairs(org.twak.utils.collections.ConsecutivePairs) Matrix4d(javax.vecmath.Matrix4d) ConsecutiveItPairs(org.twak.utils.collections.ConsecutiveItPairs) SliceParameters(org.twak.viewTrace.SliceParameters) Arrayz(org.twak.utils.collections.Arrayz) Node(com.jme3.scene.Node) ObjRead(org.twak.utils.geom.ObjRead) Map(java.util.Map) Cache(org.twak.utils.Cache) Material(com.jme3.material.Material) Point3d(javax.vecmath.Point3d) VertexBuffer(com.jme3.scene.VertexBuffer) IdentityHashMap(java.util.IdentityHashMap) Collection(java.util.Collection) Line(org.twak.utils.Line) FindLines(org.twak.viewTrace.FindLines) Set(java.util.Set) Vector2d(javax.vecmath.Vector2d) LinearForm(org.twak.utils.geom.LinearForm) Collectors(java.util.stream.Collectors) List(java.util.List) Rainbow(org.twak.utils.ui.Rainbow) Line3d(org.twak.utils.geom.Line3d) Mesh(com.jme3.scene.Mesh) Geometry(com.jme3.scene.Geometry) DBSCANClusterer(org.apache.commons.math3.ml.clustering.DBSCANClusterer) LinearForm3D(org.twak.utils.geom.LinearForm3D) Bin(org.twak.viewTrace.Bin) Pair(org.twak.utils.Pair) Vector3d(javax.vecmath.Vector3d) Clusterable(org.apache.commons.math3.ml.clustering.Clusterable) Tweed(org.twak.tweed.Tweed) ArrayList(java.util.ArrayList) TweedSettings(org.twak.tweed.TweedSettings) HashSet(java.util.HashSet) PanMouseAdaptor(org.twak.utils.PanMouseAdaptor) Graphics2D(java.awt.Graphics2D) ICanPaintU(org.twak.utils.PaintThing.ICanPaintU) Mathz(org.twak.utils.Mathz) PaintThing(org.twak.utils.PaintThing) Iterator(java.util.Iterator) Point2d(javax.vecmath.Point2d) SuperLine(org.twak.viewTrace.SuperLine) Cluster(org.apache.commons.math3.ml.clustering.Cluster) ColorRGBA(com.jme3.math.ColorRGBA) Comparator(java.util.Comparator) InAxDoubleArray(org.twak.utils.streams.InAxDoubleArray) Collections(java.util.Collections) ObjSlice(org.twak.viewTrace.ObjSlice) FindLines(org.twak.viewTrace.FindLines) Bin(org.twak.viewTrace.Bin) LinearForm(org.twak.utils.geom.LinearForm) Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine) Vector2d(javax.vecmath.Vector2d) SliceParameters(org.twak.viewTrace.SliceParameters) Point2d(javax.vecmath.Point2d) HashSet(java.util.HashSet)

Example 13 with Line

use of org.apache.commons.math3.geometry.euclidean.twod.Line in project chordatlas by twak.

the class Prof method findProfileLines.

/**
 * We find an initial base offset. Then we cluster the start point of all
 * (clean) profiles. If any are a good distance from the initial base, we
 * add those as their own profile lines.
 *
 * The original line is offset by the remaiing data.
 */
public static List<SuperLine> findProfileLines(Collection<Prof> profiles, Line3d line) {
    List<SuperLine> out = new ArrayList();
    // PaintThing.debug.clear();
    SuperLine superLine = new SuperLine(line.start.x, line.start.z, line.end.x, line.end.z);
    double outLen = superLine.length();
    double min = Double.MAX_VALUE, max = -Double.MAX_VALUE;
    Cache<Prof, Double> vLength = new Cache<Prof, Double>() {

        @Override
        public Double create(Prof i) {
            return i.verticalLength(0.5);
        }
    };
    double vLen = profiles.stream().mapToDouble(p -> vLength.get(p)).sum();
    boolean useVertical = vLen / profiles.size() > 1;
    class Wrapper implements Clusterable {

        double[] pt;

        public Wrapper(Point2d pt) {
            this.pt = new double[] { pt.x, pt.y };
        }

        @Override
        public double[] getPoint() {
            return pt;
        }
    }
    List<Wrapper> toCluster = new ArrayList();
    List<Double> baseLineOffset = new ArrayList();
    for (Prof p : profiles) {
        if (// vLen / (5*profiles.size()))
        useVertical && vLength.get(p) < 1)
            continue;
        Prof clean = p.parameterize();
        Point2d pt = clean.get(0);
        Point3d pt3 = clean.to3d(pt);
        double ppram = superLine.findPPram(new Point2d(pt3.x, pt3.z));
        baseLineOffset.add(pt.x);
        toCluster.add(new Wrapper(new Point2d(pt.x, ppram * outLen)));
        min = Math.min(min, ppram);
        max = Math.max(max, ppram);
    }
    if (min == max || toCluster.isEmpty())
        return out;
    if (true) {
        baseLineOffset.sort(Double::compareTo);
        double modeBaselineOffset = baseLineOffset.get(baseLineOffset.size() / 2);
        DBSCANClusterer<Wrapper> cr = new DBSCANClusterer<>(1.5, 0);
        List<Cluster<Wrapper>> results = cr.cluster(toCluster);
        Iterator<Cluster<Wrapper>> cit = results.iterator();
        while (cit.hasNext()) {
            Cluster<Wrapper> cw = cit.next();
            if (cw.getPoints().size() < 2 / TweedSettings.settings.profileHSampleDist) {
                cit.remove();
                double cMeanY = cw.getPoints().stream().mapToDouble(x -> x.pt[1]).average().getAsDouble();
                double bestDist = Double.MAX_VALUE;
                Cluster<Wrapper> bestWrapper = null;
                for (Cluster<Wrapper> near : results) {
                    double meanY = near.getPoints().stream().mapToDouble(x -> x.pt[1]).average().getAsDouble();
                    double dist = Math.abs(meanY - cMeanY);
                    if (dist < bestDist) {
                        bestDist = dist;
                        bestWrapper = near;
                    }
                }
                if (bestWrapper != null)
                    bestWrapper.getPoints().addAll(cw.getPoints());
            }
        }
        {
            baseLineOffset.clear();
            int c = 0;
            for (Cluster<Wrapper> cw : results) {
                double[] minMax = cw.getPoints().stream().map(p -> new double[] { p.pt[1] }).collect(new InAxDoubleArray());
                double[] offsetA = cw.getPoints().stream().mapToDouble(p -> p.pt[0]).sorted().toArray();
                double offset = offsetA[offsetA.length / 2];
                if (offset - modeBaselineOffset < 1) {
                    for (Wrapper w : cw.getPoints()) baseLineOffset.add(w.pt[0]);
                    continue;
                }
                SuperLine sl = new SuperLine(superLine.fromPPram(minMax[0] / outLen), superLine.fromPPram(minMax[1] / outLen));
                sl.moveLeft(offset);
                out.add(sl);
                List<Point2d> pts = cw.getPoints().stream().map(w -> new Point2d(w.pt[0], w.pt[1])).collect(Collectors.toList());
                PaintThing.debug(Rainbow.getColour(c++), 1, pts);
            }
        }
    }
    Point2d nStart = superLine.fromPPram(min), nEnd = superLine.fromPPram(max);
    superLine.start = nStart;
    superLine.end = nEnd;
    baseLineOffset.sort(Double::compare);
    if (!baseLineOffset.isEmpty())
        superLine.moveLeft(baseLineOffset.get(baseLineOffset.size() / 2));
    out.add(0, superLine);
    return out;
}
Also used : ConsecutivePairs(org.twak.utils.collections.ConsecutivePairs) Matrix4d(javax.vecmath.Matrix4d) ConsecutiveItPairs(org.twak.utils.collections.ConsecutiveItPairs) SliceParameters(org.twak.viewTrace.SliceParameters) Arrayz(org.twak.utils.collections.Arrayz) Node(com.jme3.scene.Node) ObjRead(org.twak.utils.geom.ObjRead) Map(java.util.Map) Cache(org.twak.utils.Cache) Material(com.jme3.material.Material) Point3d(javax.vecmath.Point3d) VertexBuffer(com.jme3.scene.VertexBuffer) IdentityHashMap(java.util.IdentityHashMap) Collection(java.util.Collection) Line(org.twak.utils.Line) FindLines(org.twak.viewTrace.FindLines) Set(java.util.Set) Vector2d(javax.vecmath.Vector2d) LinearForm(org.twak.utils.geom.LinearForm) Collectors(java.util.stream.Collectors) List(java.util.List) Rainbow(org.twak.utils.ui.Rainbow) Line3d(org.twak.utils.geom.Line3d) Mesh(com.jme3.scene.Mesh) Geometry(com.jme3.scene.Geometry) DBSCANClusterer(org.apache.commons.math3.ml.clustering.DBSCANClusterer) LinearForm3D(org.twak.utils.geom.LinearForm3D) Bin(org.twak.viewTrace.Bin) Pair(org.twak.utils.Pair) Vector3d(javax.vecmath.Vector3d) Clusterable(org.apache.commons.math3.ml.clustering.Clusterable) Tweed(org.twak.tweed.Tweed) ArrayList(java.util.ArrayList) TweedSettings(org.twak.tweed.TweedSettings) HashSet(java.util.HashSet) PanMouseAdaptor(org.twak.utils.PanMouseAdaptor) Graphics2D(java.awt.Graphics2D) ICanPaintU(org.twak.utils.PaintThing.ICanPaintU) Mathz(org.twak.utils.Mathz) PaintThing(org.twak.utils.PaintThing) Iterator(java.util.Iterator) Point2d(javax.vecmath.Point2d) SuperLine(org.twak.viewTrace.SuperLine) Cluster(org.apache.commons.math3.ml.clustering.Cluster) ColorRGBA(com.jme3.math.ColorRGBA) Comparator(java.util.Comparator) InAxDoubleArray(org.twak.utils.streams.InAxDoubleArray) Collections(java.util.Collections) ObjSlice(org.twak.viewTrace.ObjSlice) ArrayList(java.util.ArrayList) Cluster(org.apache.commons.math3.ml.clustering.Cluster) Clusterable(org.apache.commons.math3.ml.clustering.Clusterable) InAxDoubleArray(org.twak.utils.streams.InAxDoubleArray) Point2d(javax.vecmath.Point2d) Point3d(javax.vecmath.Point3d) SuperLine(org.twak.viewTrace.SuperLine) List(java.util.List) ArrayList(java.util.ArrayList) DBSCANClusterer(org.apache.commons.math3.ml.clustering.DBSCANClusterer) Cache(org.twak.utils.Cache)

Example 14 with Line

use of org.apache.commons.math3.geometry.euclidean.twod.Line in project chordatlas by twak.

the class SkelFootprint method mergeOnProfiles.

private void mergeOnProfiles(HalfMesh2 mesh, List<Line> footprint) {
    System.out.println("merging over profiles...");
    TreeSet<HalfFace> togo = new TreeSet<>((HalfFace o1, HalfFace o2) -> Double.compare(o1.area(), o2.area()));
    togo.addAll(mesh.faces);
    int count = 0;
    while (!togo.isEmpty()) {
        HalfFace f = togo.pollFirst();
        Cache<HalfEdge, MutableDouble> crossedBy = new Cach<>(e -> new MutableDouble(0));
        for (HalfEdge e : f) {
            SuperEdge se = (SuperEdge) e;
            if (se.profLine != null) {
                MegaFacade mf = ((SuperLine) se.profLine).mega;
                if (mf != null)
                    for (Prof p : mf.getTween(se.start, se.end, 0)) {
                        Line proj = new Line(Pointz.to2(p.to3d(p.get(0))), Pointz.to2(p.to3d(p.get(p.size() - 1))));
                        for (HalfEdge e2 : f) {
                            SuperEdge se2 = (SuperEdge) e2;
                            if (se2.profLine == null && (se2.over == null || ((SuperEdge) se2.over).profLine == null) && e2.over != null && e2.line().intersects(proj) != null && Mathz.inRange(e2.line().absAngle(proj), 0.25 * Math.PI, 0.75 * Math.PI)) {
                                crossedBy.get(e2).d += TweedSettings.settings.profileHSampleDist;
                            }
                        }
                    }
            }
        }
        count += crossedBy.cache.size();
        Optional<Map.Entry<HalfEdge, MutableDouble>> longestO = crossedBy.cache.entrySet().stream().filter(// 
        e1 -> ((SuperEdge) e1.getKey()).profLine == null && e1.getValue().d > 0).max((e1, e2) -> Double.compare(e1.getValue().d, e2.getValue().d));
        if (longestO.isPresent()) {
            Map.Entry<HalfEdge, MutableDouble> longest = longestO.get();
            if (longest.getValue().d > 0.6 * longest.getKey().length()) {
                HalfFace tgf = longest.getKey().over.face;
                togo.remove(tgf);
                longest.getKey().face.merge(mesh, tgf);
                ((SuperFace) longest.getKey().face).mergeFrom((SuperFace) tgf);
                togo.add(f);
            }
        }
    }
    System.out.println("found crossings " + count);
    killDoubleEdges(mesh);
}
Also used : Color(java.awt.Color) XStream(com.thoughtworks.xstream.XStream) Arrays(java.util.Arrays) FloatBuffer(java.nio.FloatBuffer) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) Type(com.jme3.scene.VertexBuffer.Type) Arrayz(org.twak.utils.collections.Arrayz) Loop(org.twak.utils.collections.Loop) Node(com.jme3.scene.Node) SkelGen(org.twak.tweed.gen.skel.SkelGen) MutableDouble(org.twak.utils.MutableDouble) ColorRGBAPainter(org.twak.viewTrace.ColorRGBAPainter) Map(java.util.Map) Cache(org.twak.utils.Cache) Material(com.jme3.material.Material) ChangeListener(javax.swing.event.ChangeListener) Streamz(org.twak.utils.collections.Streamz) Point3d(javax.vecmath.Point3d) ChangeEvent(javax.swing.event.ChangeEvent) VertexBuffer(com.jme3.scene.VertexBuffer) LoopL(org.twak.utils.collections.LoopL) Predicate(java.util.function.Predicate) Line(org.twak.utils.Line) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) Set(java.util.Set) HalfMesh2(org.twak.utils.geom.HalfMesh2) CollisionResult(com.jme3.collision.CollisionResult) Vector2d(javax.vecmath.Vector2d) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) List(java.util.List) JSlider(javax.swing.JSlider) Optional(java.util.Optional) Rainbow(org.twak.utils.ui.Rainbow) CollisionResults(com.jme3.collision.CollisionResults) Mesh(com.jme3.scene.Mesh) Geometry(com.jme3.scene.Geometry) IntStream(java.util.stream.IntStream) ActionListener(java.awt.event.ActionListener) DBSCANClusterer(org.apache.commons.math3.ml.clustering.DBSCANClusterer) Vector2f(com.jme3.math.Vector2f) HashMap(java.util.HashMap) MiniFacade(org.twak.viewTrace.facades.MiniFacade) Cach(org.twak.utils.Cach) Plot(org.twak.utils.ui.Plot) SwingConstants(javax.swing.SwingConstants) TreeSet(java.util.TreeSet) Clusterable(org.apache.commons.math3.ml.clustering.Clusterable) Tweed(org.twak.tweed.Tweed) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) ArrayList(java.util.ArrayList) TweedSettings(org.twak.tweed.TweedSettings) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Mathz(org.twak.utils.Mathz) PaintThing(org.twak.utils.PaintThing) NoSuchElementException(java.util.NoSuchElementException) ProgressMonitor(javax.swing.ProgressMonitor) LinkedHashSet(java.util.LinkedHashSet) MatParam(com.jme3.material.MatParam) JButton(javax.swing.JButton) Texture2D(com.jme3.texture.Texture2D) Iterator(java.util.Iterator) MultiMap(org.twak.utils.collections.MultiMap) BufferUtils(com.jme3.util.BufferUtils) Vector3f(com.jme3.math.Vector3f) MeshBuilder(org.twak.siteplan.jme.MeshBuilder) MegaFacade(org.twak.tweed.gen.ProfileGen.MegaFacade) ModeCollector(org.twak.viewTrace.ModeCollector) JOptionPane(javax.swing.JOptionPane) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) ActionEvent(java.awt.event.ActionEvent) File(java.io.File) Loopz(org.twak.utils.collections.Loopz) Point2d(javax.vecmath.Point2d) Jme3z(org.twak.siteplan.jme.Jme3z) Ray(com.jme3.math.Ray) SuperLine(org.twak.viewTrace.SuperLine) LineHeight(org.twak.viewTrace.facades.LineHeight) Format(com.jme3.scene.VertexBuffer.Format) Cluster(org.apache.commons.math3.ml.clustering.Cluster) ColorRGBA(com.jme3.math.ColorRGBA) FileReader(java.io.FileReader) ImageRaster(com.jme3.texture.image.ImageRaster) Comparator(java.util.Comparator) Collections(java.util.Collections) MutableDouble(org.twak.utils.MutableDouble) MegaFacade(org.twak.tweed.gen.ProfileGen.MegaFacade) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine) TreeSet(java.util.TreeSet) SuperLine(org.twak.viewTrace.SuperLine) Cach(org.twak.utils.Cach) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) MultiMap(org.twak.utils.collections.MultiMap)

Example 15 with Line

use of org.apache.commons.math3.geometry.euclidean.twod.Line in project imagej-ops by imagej.

the class DefaultConvexHull3D method getV2.

/**
 * Finds the vertex with the largest distance to the line described by v0, v1.
 *
 * @param v0 Vertex of the line.
 * @param v1 Vertex of the line.
 * @return Vertex with the largest distance.
 */
private Vertex getV2(final double epsilon, final Set<Vertex> vertices, final Vertex v0, final Vertex v1) {
    Iterator<Vertex> it = vertices.iterator();
    // v0 -------------------------------------v1
    // |
    // | d
    // |
    // * v
    // 
    // d = |(v - v0) x (v - v1)| / |(v1 - v0)|
    // We can omit the common denominator because it does not change over
    // all computations.
    double distLinePoint = epsilon;
    Vertex v2 = null;
    while (it.hasNext()) {
        Vertex v = it.next();
        Vector3D d0 = v.subtract(v1);
        Vector3D d1 = v.subtract(v0);
        double lengthSq = d0.crossProduct(d1).getNormSq();
        if (lengthSq > distLinePoint) {
            distLinePoint = lengthSq;
            v2 = v;
        }
    }
    return v2;
}
Also used : Vertex(net.imagej.ops.geom.geom3d.mesh.Vertex) Vector3D(org.apache.commons.math3.geometry.euclidean.threed.Vector3D)

Aggregations

ArrayList (java.util.ArrayList)9 Line (org.twak.utils.Line)8 Plot2 (ij.gui.Plot2)7 List (java.util.List)7 Map (java.util.Map)7 Set (java.util.Set)7 Point2d (javax.vecmath.Point2d)7 HashSet (java.util.HashSet)6 Collectors (java.util.stream.Collectors)6 Pair (org.twak.utils.Pair)6 Iterator (java.util.Iterator)5 Point3d (javax.vecmath.Point3d)5 Vector2d (javax.vecmath.Vector2d)5 PointValuePair (org.apache.commons.math3.optim.PointValuePair)5 Tweed (org.twak.tweed.Tweed)5 TweedSettings (org.twak.tweed.TweedSettings)5 Material (com.jme3.material.Material)4 ColorRGBA (com.jme3.math.ColorRGBA)4 Geometry (com.jme3.scene.Geometry)4 Mesh (com.jme3.scene.Mesh)4