Search in sources :

Example 1 with Bounds

use of org.twak.utils.geom.DRectangle.Bounds in project chordatlas by twak.

the class Regularizer method cluster1.

private void cluster1(List<FRect> rects, double tol, double alpha, Bounds... axis) {
    class Wrapper {

        FRect rect;

        public Wrapper(FRect rect) {
            this.rect = rect;
        }

        public void set(double neu, Bounds b) {
            double old = rect.get(b);
            rect.set(b, neu * alpha + old * (1 - alpha));
        }
    }
    if (rects.isEmpty())
        return;
    for (Bounds b : axis) {
        List<Wrapper> toCluster = new ArrayList<>();
        for (FRect r : rects) toCluster.add(new Wrapper(r));
        DumbCluster1D<Wrapper> clusterer = new DumbCluster1D<Wrapper>(tol, toCluster) {

            @Override
            public double toDouble(Wrapper e) {
                return e.rect.get(b);
            }
        };
        for (DumbCluster1D.Cluster<Wrapper> e : clusterer) for (Wrapper w : e.things) w.set(e.mean, b);
    }
}
Also used : Bounds(org.twak.utils.geom.DRectangle.Bounds) ArrayList(java.util.ArrayList) DumbCluster1D(org.twak.utils.DumbCluster1D)

Example 2 with Bounds

use of org.twak.utils.geom.DRectangle.Bounds in project chordatlas by twak.

the class Regularizer method average.

private DRectangle average(FRect... rs_) {
    FRect out = new FRect();
    List<FRect> rs = new ArrayList();
    for (FRect f : rs_) rs.add(f);
    for (int r1 = 0; r1 < rs.size(); r1++) {
        // overlapping features
        FRect f1 = rs.get(r1);
        for (int r2 = 0; r2 < rs.size(); r2++) {
            FRect f2 = rs.get(r2);
            if (r2 == r1 || f2.area() > f1.area())
                continue;
            double area = f2.union(f1).area();
            if (area * 0.7 > f1.area()) {
                rs.remove(r2);
                if (r2 < r1)
                    r1--;
                r2--;
            }
        }
    }
    // while (fit.hasNext()) {
    // FRect i = fit.next();
    // 
    // for (FRect f : new Array)
    // 
    // }
    boolean onlyInGrid = rs.stream().mapToInt(r -> r.outer == null ? 0 : 1).sum() >= 1;
    for (Bounds b : new Bounds[] { Bounds.XMIN, Bounds.XMAX, Bounds.YMIN, Bounds.YMAX }) {
        double norm = 0, avg = 0;
        for (FRect r : rs) {
            if (onlyInGrid && r.outer == null)
                continue;
            double sl = r.sideLength(b);
            norm += sl;
            avg += r.get(b) * sl;
        }
        out.set(b, avg / norm);
    }
    return out;
}
Also used : Bounds(org.twak.utils.geom.DRectangle.Bounds) ArrayList(java.util.ArrayList)

Example 3 with Bounds

use of org.twak.utils.geom.DRectangle.Bounds in project chordatlas by twak.

the class MiniFacade method getDistance.

@Override
public double getDistance(Point2d pt) {
    pt = flip(pt);
    if (contains(pt))
        return 0;
    double dist = Double.MAX_VALUE;
    for (Bounds b : new Bounds[] { XMIN, YMIN, XMAX, YMAX }) {
        Line l = getAsRect().getEdge(b);
        dist = Math.min(dist, l.distance(pt));
    }
    return dist;
}
Also used : Line(org.twak.utils.Line) Bounds(org.twak.utils.geom.DRectangle.Bounds)

Example 4 with Bounds

use of org.twak.utils.geom.DRectangle.Bounds in project chordatlas by twak.

the class Regularizer method clusterDeltas.

private void clusterDeltas(List<FRect> rects, double tol, double alpha, Dir dir) {
    if (rects.isEmpty())
        return;
    List<FRect> toCluster = new ArrayList<>();
    for (FRect r : rects) {
        FRect da = r.getAdj(dir);
        if (// only strong adjacencies
        da != null && da.getAdj(dir.opposite) == r)
            toCluster.add(r);
    }
    DumbCluster1D<FRect> clusterer = new DumbCluster1D<FRect>(tol, toCluster) {

        @Override
        public double toDouble(FRect rect) {
            return rect.distanceToAdjacent(dir);
        }
    };
    Bounds b = (dir == Dir.L || dir == Dir.R) ? Bounds.XCEN : Bounds.YCEN;
    int moveDirection = dir == Dir.L || dir == Dir.D ? 1 : -1;
    Map<FRect, Double> desiredSpacings = new HashMap<>();
    for (DumbCluster1D.Cluster<FRect> e : clusterer) {
        for (FRect rect : e.things) desiredSpacings.put(rect, e.mean);
    }
    Collections.sort(rects, DRectangle.comparator(b, dir == Dir.L || dir == Dir.D ? false : true));
    for (FRect r : rects) {
        Double spacing = desiredSpacings.get(r);
        if (spacing == null)
            continue;
        DRectangle adj = r.getAdj(dir);
        adj.set(b, adj.get(b) - (spacing - r.distanceToAdjacent(dir)) * alpha * moveDirection);
    }
}
Also used : DRectangle(org.twak.utils.geom.DRectangle) HashMap(java.util.HashMap) Bounds(org.twak.utils.geom.DRectangle.Bounds) ArrayList(java.util.ArrayList) DumbCluster1D(org.twak.utils.DumbCluster1D) OptionalDouble(java.util.OptionalDouble) InAxDouble(org.twak.utils.streams.InAxDouble)

Example 5 with Bounds

use of org.twak.utils.geom.DRectangle.Bounds in project chordatlas by twak.

the class Regularizer method combine.

private MiniFacade combine(List<MiniFacade> in) {
    MiniFacade out = new MiniFacade();
    out.left = lp;
    out.width = rp - lp;
    out.imageFeatures = in.get(0).imageFeatures;
    out.color = new double[] { 0, 0, 0, 1 };
    out.groundColor = new double[] { 0, 0, 0, 1 };
    int gcc = 0;
    for (MiniFacade mf : in) for (int i = 0; i < 3; i++) {
        out.color[i] += mf.color[i];
        if (mf.groundColor != null) {
            out.groundColor[i] += mf.groundColor[i];
            gcc++;
        }
    }
    for (int i = 0; i < 3; i++) {
        out.color[i] /= in.size();
        if (gcc > 0)
            out.groundColor[i] /= gcc;
    }
    Cache2<Outer, Integer, List<FRect>> corniceX = new ArrayCache2();
    Cache2<Outer, Integer, List<FRect>> sillX = new ArrayCache2();
    Cache2<Outer, Integer, List<FRect>> balX = new ArrayCache2();
    out.height = in.stream().mapToDouble(mf -> mf.height).average().getAsDouble();
    out.groundFloorHeight = in.stream().mapToDouble(mf -> mf.groundFloorHeight).average().getAsDouble();
    for (int i = 0; i < ids; i++) {
        int yay = 0, nay = 0;
        int ii = i;
        List<FRect> found = in.stream().map(mf -> m2i2r.get(mf, ii)).filter(x -> x != null).flatMap(l -> l.stream()).collect(Collectors.toList());
        Point2d avg = found.stream().map(r -> r.getCenter()).collect(new Point2DMeanCollector());
        for (MiniFacade mf : in) {
            List<FRect> r = m2i2r.get(mf, i);
            if (mf.contains(avg)) {
                if (r.isEmpty()) {
                    if (mf.left + 3 < avg.x && mf.left + mf.width - 3 > avg.x)
                        nay++;
                } else
                    yay++;
            }
        }
        if (yay >= nay) {
            // if we believe it exists add it as average of observed sizes
            FRect o;
            if (dimensionSpread(found) > 1.4) {
                // scattered -> union (typically shop windows)
                o = new FRect(found.get(0));
                for (FRect n : found) o.setFrom(o.union(n));
            } else
                // about same size: average position: windows on a grid
                o = new FRect(average(found.toArray(new FRect[found.size()])));
            {
                FRect t = found.get(0);
                o.f = t.f;
                o.id = i;
                o.outer = null;
                o.attachedHeight.get(Feature.SILL).d = averageAttached(o, Feature.SILL, found);
                o.attachedHeight.get(Feature.CORNICE).d = averageAttached(o, Feature.CORNICE, found);
                o.attachedHeight.get(Feature.BALCONY).d = averageAttached(o, Feature.BALCONY, found);
                if (t.f == Feature.WINDOW || t.f == Feature.SHOP) {
                    for (FRect r : found) {
                        corniceX.get(r.outer, r.yi).add(o);
                        sillX.get(r.outer, r.yi).add(o);
                        balX.get(r.outer, r.yi).add(o);
                    }
                }
            }
            out.rects.put(o.f, o);
        }
    }
    spreadAttachedOverGrid(Feature.SILL, sillX);
    spreadAttachedOverGrid(Feature.CORNICE, corniceX);
    spreadAttachedOverGrid(Feature.BALCONY, balX);
    fixOverlaps(out);
    mergeRemoveSmall(out);
    DRectangle mr = out.getAsRect();
    // ensure everything is comfortably within the bounds
    mr.width -= 0.2;
    mr.x += 0.1;
    for (Feature f : Feature.values()) {
        // clip to all
        Iterator<FRect> rit = out.rects.get(f).iterator();
        while (rit.hasNext()) {
            FRect r = rit.next();
            DRectangle section = r.intersect(mr);
            if (section == null || section.area() < 0.5)
                rit.remove();
            else
                r.setFrom(section);
        }
    }
    {
        // door height
        Double hf = Double.valueOf(0);
        while (out.groundFloorHeight < 6 && ((hf = horizontalEmpty(out, out.groundFloorHeight)) != null)) out.groundFloorHeight = hf + 0.3;
        if (out.groundFloorHeight >= 6)
            // no ground floor!
            out.groundFloorHeight = 0;
    }
    return out;
}
Also used : DumbCluster1D(org.twak.utils.DumbCluster1D) Cache2(org.twak.utils.Cache2) OptionalDouble(java.util.OptionalDouble) HashMap(java.util.HashMap) CountThings(org.twak.utils.collections.CountThings) Pair(org.twak.utils.Pair) TreeSet(java.util.TreeSet) MapMapList(org.twak.utils.collections.MapMapList) ArrayList(java.util.ArrayList) Arrayz(org.twak.utils.collections.Arrayz) HashSet(java.util.HashSet) Map(java.util.Map) Mathz(org.twak.utils.Mathz) Streamz(org.twak.utils.collections.Streamz) LinkedHashSet(java.util.LinkedHashSet) InAxDouble(org.twak.utils.streams.InAxDouble) Iterator(java.util.Iterator) ImageFeatures(org.twak.tweed.gen.FeatureCache.ImageFeatures) MultiMap(org.twak.utils.collections.MultiMap) Set(java.util.Set) Vector2d(javax.vecmath.Vector2d) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) Collectors(java.util.stream.Collectors) File(java.io.File) Cluster(org.twak.utils.DumbCluster1D.Cluster) Point2d(javax.vecmath.Point2d) List(java.util.List) DumbCluster1DImpl(org.twak.utils.DumbCluster1DImpl) Bounds(org.twak.utils.geom.DRectangle.Bounds) DRectangle(org.twak.utils.geom.DRectangle) Comparator(java.util.Comparator) Collections(java.util.Collections) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) DRectangle(org.twak.utils.geom.DRectangle) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) OptionalDouble(java.util.OptionalDouble) InAxDouble(org.twak.utils.streams.InAxDouble) Point2d(javax.vecmath.Point2d) MapMapList(org.twak.utils.collections.MapMapList) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

Bounds (org.twak.utils.geom.DRectangle.Bounds)5 ArrayList (java.util.ArrayList)4 DumbCluster1D (org.twak.utils.DumbCluster1D)3 HashMap (java.util.HashMap)2 OptionalDouble (java.util.OptionalDouble)2 DRectangle (org.twak.utils.geom.DRectangle)2 InAxDouble (org.twak.utils.streams.InAxDouble)2 File (java.io.File)1 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 TreeSet (java.util.TreeSet)1 Collectors (java.util.stream.Collectors)1 Point2d (javax.vecmath.Point2d)1 Vector2d (javax.vecmath.Vector2d)1