use of org.twak.utils.Line in project chordatlas by twak.
the class SkelFootprint method findProfiles.
private void findProfiles(List<Line> footprint, List<Prof> globalProfs) {
MultiMap<SuperLine, List<Prof>> profSets = new MultiMap<>();
System.out.println("clustering " + globalProfs.size() + " profiles over sweep edges...");
for (Line l : footprint) profileRuns((SuperLine) l, profSets);
Prof example = null;
System.out.println("cleaning " + profSets.values().stream().flatMap(c -> c.stream()).count() + " profiles...");
for (SuperLine sl : profSets.keySet()) for (List<Prof> lp : profSets.get(sl)) {
if (example == null)
example = lp.get(0);
Prof p = Prof.parameterize(lp);
if (p != null && p.size() > 1)
globalProfs.add(SkelGen.moveToX0(p));
}
Iterator<Prof> git = globalProfs.iterator();
int c = 0;
// remove trivial
while (git.hasNext()) {
Prof p = git.next();
if (p.size() < 2)
git.remove();
else if (p.size() == 2) {
if (p.get(0).x == p.get(1).x) {
git.remove();
c++;
}
} else if (p.size() == 3) {
if (p.get(0).x == p.get(1).x && p.get(2).y == p.get(1).y)
git.remove();
}
}
System.out.println("found " + globalProfs.size() + " interesting profiles" + " from " + profSets.size() + " runs");
removeSimilarB(globalProfs, TweedSettings.settings.profilePrune);
System.out.println("after remove similar " + globalProfs.size());
// insert single vertical profile
{
Prof vertical = defaultProf(example);
globalProfs.add(0, vertical);
}
}
use of org.twak.utils.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);
}
use of org.twak.utils.Line in project chordatlas by twak.
the class SuperEdge method findRange.
public double[] findRange() {
if (mini == null || mini.isEmpty() || mini.get(0).imageFeatures == null)
return null;
// todo: bad place for this method.
Line mf = mini.get(0).imageFeatures.mega.megafacade;
double mfL = mf.length();
return new double[] { mf.findPPram(start) * mfL, mf.findPPram(end) * mfL };
}
use of org.twak.utils.Line in project chordatlas by twak.
the class VizSkelGen method toHalf.
private SuperFace toHalf(Loop<Point3d> loop) {
Cache<Point3d, Point2d> look = new Cach<>(x -> Pointz.to2(x));
HalfEdge last = null, first = null;
SuperFace out = new SuperFace();
for (Loopable<Point3d> edge : loop.loopableIterator()) {
SuperEdge e = new SuperEdge(look.get(edge.get()), look.get(edge.getNext().get()), null);
if (first == null)
first = e;
if (last != null)
last.next = e;
e.face = out;
// !
e.prof = null;
e.mini = Collections.EMPTY_LIST;
if (mode == Mode.Profiles)
for (Line l : footprint) {
if (l.absAngle(e.line()) < 0.1 && l.distance(e.start, true) < 1.5 && l.distance(e.end, true) < 1.5) {
SuperLine sl = (SuperLine) l;
MegaFacade mf = sl.getMega();
e.prof = findProf(e.start, e.end, sl, mf);
}
}
last = e;
}
last.next = first;
out.e = first;
SkelFootprint.meanModeHeightColor(Loopz.toXZLoop(loop), out, blockGen);
if (mode == Mode.CE) {
for (HalfEdge ee : out) {
SuperEdge e = (SuperEdge) ee;
Matrix4d m = new Matrix4d();
m.setIdentity();
e.prof = new Prof(m, new Vector3d());
e.prof.add(new Point2d(0, 0));
e.prof.add(new Point2d(0, out.height));
e.prof.add(new Point2d(-1, out.height + 1));
}
}
return out;
}
use of org.twak.utils.Line 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;
}
Aggregations