Search in sources :

Example 1 with Result

use of org.twak.viewTrace.RangeMerge.Result in project chordatlas by twak.

the class FindLines method forClique.

private void forClique(Set<Line> remaining, List<Line> out, int debugLine, int clique) {
    Iterator<Line> filter = remaining.iterator();
    while (filter.hasNext()) {
        Line l = filter.next();
        // double l = filter.next().length();
        if (l.lengthSquared() == 0 || l.hasNaN())
            filter.remove();
    }
    if (remaining.isEmpty())
        return;
    int count = 0;
    while (!remaining.isEmpty()) {
        double angle = nextAngle(remaining, count);
        // offset bin
        Bin.Builder<Line> oBBin = new Bin.Builder<>();
        LinearForm lfPerp = new LinearForm(Math.cos(angle), Math.sin(angle));
        for (Line l : remaining) {
            if (Anglez.dist(l.aTan2(), angle) < Math.PI / 2) {
                // and line angle near angle+-180
                oBBin.add(lfPerp.findPParam(l.start), l.length(), l);
                oBBin.add(lfPerp.findPParam(l.end), l.length(), l);
            }
        }
        // we're super sensitive to the number of orientation bins :(
        Bin<Line> oBin = oBBin.done(P.FL_BINS * 2, false);
        int oBinI = oBin.maxI();
        int[] oBinM = oBin.maxMode(1, 10);
        LinearForm lfDir = new LinearForm(lfPerp.y, -lfPerp.x);
        lfDir.findC(lfPerp.fromPParam(oBin.val(oBinI)));
        RangeMerge<Line> rm = new RangeMerge(P.FL_GAP_TOL, P.FL_GAP_TOL / 2);
        for (Line w : oBin.getThings(oBinI, oBinM)) {
            if (lfDir.distance(w.start) < getTolNearLine(w.start) && lfDir.distance(w.end) < getTolNearLine(w.end) && // and line angle near angle+-180
            Anglez.dist(w.aTan2(), angle) < Math.PI / 2.5) {
                rm.add(lfDir.findPParam(w.start), lfDir.findPParam(w.end), w);
            }
        }
        List<Result<Line>> merged = rm.getResults();
        if (merged.isEmpty()) {
            for (Line w : oBin.getThings(oBinI, oBinM)) remaining.remove(w);
        } else {
            double maxP = merged.stream().map(x -> x.max - x.min).max(Double::compare).get();
            for (Result<Line> r : merged) {
                if (r.max - r.min < 0.2 * maxP)
                    continue;
                Line line = null;
                if (P.FL_REGRESS)
                    line = regress(r.things, lfDir);
                if (line == null)
                    line = new Line(lfDir, r.min, r.max);
                Iterator<Line> rit = remaining.iterator();
                boolean removed = false;
                Bin<Line> counts = null;
                if (P.MIN_LINES > 1)
                    counts = new Bin<>(0, 1, 50, false);
                while (rit.hasNext()) {
                    Line rine = rit.next();
                    if (line.distance(rine.start, true) < getTolNearLine2(rine.start) && line.distance(rine.end, true) < getTolNearLine2(rine.end) && Anglez.dist(line.aTan2(), rine.aTan2()) < getTolRemoveAngle(rine)) {
                        if (counts != null)
                            counts.addRange(line.findPPram(rine.start), line.findPPram(rine.end), 1, rine);
                        removed = true;
                        rit.remove();
                    }
                }
                if (counts != null) {
                    // for (Pair<Double, Double > d : new ConsecutiveItPairs<>( counts.getRegionAbove( P.MIN_LINES ) )) {
                    // 
                    // Point2d start = line.fromPPram( counts.getFirst( P.MIN_LINES ) ),
                    // end   = line.fromPPram( counts.getLast( P.MIN_LINES ) );
                    // 
                    // if ( start != null && end != null ) {
                    // out.add( new Line(start, end) );
                    // }
                    // }
                    Point2d start = line.fromPPram(counts.getFirst(P.MIN_LINES)), end = line.fromPPram(counts.getLast(P.MIN_LINES));
                    if (start != null && end != null) {
                        line.start = start;
                        line.end = end;
                    } else
                        line = null;
                }
                if (!removed)
                    for (Line l : r.things) {
                        if (remaining.contains(l)) {
                            remaining.remove(l);
                        }
                    }
                if (line != null) {
                    if (bias != null) {
                        Point2d cen = line.fromPPram(0.5);
                        Double toGIS = bias.getAngle(line, cen);
                        if (toGIS != null)
                            line = rotateToAngle(line, cen, toGIS);
                    }
                    if (debugFilter(count, debugLine) && line.start.distanceSquared(line.end) > 0.001) {
                        out.add(line);
                        cliques.put(line, clique);
                    }
                }
            }
        }
        count++;
    }
}
Also used : LinearForm(org.twak.utils.geom.LinearForm) Result(org.twak.viewTrace.RangeMerge.Result) Line(org.twak.utils.Line) Point2d(javax.vecmath.Point2d)

Aggregations

Point2d (javax.vecmath.Point2d)1 Line (org.twak.utils.Line)1 LinearForm (org.twak.utils.geom.LinearForm)1 Result (org.twak.viewTrace.RangeMerge.Result)1