use of javax.vecmath.Point2d in project chordatlas by twak.
the class Concarnie method tidy.
private void tidy(Graph2D graph) {
UnionWalker uw = new UnionWalker();
for (Point2d a : graph.map.keySet()) {
for (Line l : graph.get(a)) {
uw.addEdge(l.start, l.end);
// PaintThing.debug.put("flibble", l);
}
}
out = uw.findAll();
// if (false)
for (Loop<Point2d> loop : out) {
for (Loopable<Point2d> pt : loop.loopableIterator()) {
Line prev = findSupporting(pt, 1), next = findSupporting(pt, -1);
if (prev != null && next != null) {
Point2d bestFit = prev.intersects(next, false);
if (bestFit != null && pt.get().distance(bestFit) < P.CON_TOL && // if nearer other ends of lines, don't use
bestFit.distanceSquared(prev.start) < bestFit.distanceSquared(prev.end) && bestFit.distanceSquared(next.end) < bestFit.distanceSquared(next.start)) {
pt.get().set(bestFit);
}
}
}
}
Iterator<Loop<Point2d>> lit = out.iterator();
// if (false)
while (lit.hasNext()) {
Loop<Point2d> loop = lit.next();
Loopable<Point2d> start = loop.start, current = start;
int size = loop.count();
boolean again;
do {
again = false;
Point2d a = current.getPrev().get(), b = current.get(), c = current.getNext().get();
Line ab = new Line(a, b), bc = new Line(b, c);
double angle = Anglez.dist(ab.aTan2(), bc.aTan2());
if (// corner filter moves corners to same point!
a.distanceSquared(b) < 0.0001 || b.distanceSquared(c) < 0.0001 || // nearly parallel, but small area removed
angle < 0.2 && Math.abs(Mathz.area(a, b, c)) < 50 * P.CON_TOL * P.CON_TOL) // ab.length() + bc.length() > TOL/2 &&
// angle > Math.PI - 0.1 ) // pointy corner
// a.distanceSquared(c) < 0.0001 )
{
current.getPrev().setNext(current.getNext());
current.getNext().setPrev(current.getPrev());
size--;
if (start == current)
loop.start = start = current.getPrev();
again = true;
current = current.getPrev();
} else
current = current.getNext();
} while ((again || current != start) && size > 2);
if (size <= 2)
lit.remove();
}
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class Concarnie method mergeConsecutive.
private List<Portal> mergeConsecutive(Set<Line> portals) {
// merge consecutive portals
List<Portal> portalsOut = new ArrayList();
Map<Point2d, Line> starts = new HashMap<>(), ends = new HashMap<>();
for (Line l : portals) {
Line replace = starts.put(l.start, l);
if (replace != null)
portalsOut.add(new Portal(replace));
replace = ends.put(l.end, l);
if (replace != null)
portalsOut.add(new Portal(replace));
}
while (!starts.isEmpty()) {
Portal p = new Portal();
portalsOut.add(p);
Line start = starts.entrySet().iterator().next().getValue(), current = start;
do {
p.lines.add(current);
p.length += current.length();
starts.remove(current.start);
ends.remove(current.end);
current = starts.get(current.end);
} while (current != null);
current = start;
current = ends.get(current.start);
if (current != null)
do {
p.lines.add(0, current);
p.length += current.length();
starts.remove(current.start);
ends.remove(current.end);
current = ends.get(current.start);
} while (current != null);
p.summary = new Line(p.lines.get(0).start, p.lines.get(p.lines.size() - 1).end);
}
Collections.sort(portalsOut, (a, b) -> -Double.compare(a.length, b.length));
return portalsOut;
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class LineSoup method clique.
public Map<Line, Integer> clique(double highTol, double lowTol) {
int currentC = 0;
Graph2D lookup = new Graph2D(all);
Set<Line> remaining = new LinkedHashSet<>(all), visited = new HashSet<>();
Map<Line, Integer> out = new HashMap<>();
while (!remaining.isEmpty()) {
Set<Line> queue = new LinkedHashSet<>();
queue.add(remaining.iterator().next());
while (!queue.isEmpty()) {
Line l = queue.iterator().next();
queue.remove(l);
remaining.remove(l);
visited.add(l);
out.put(l, currentC);
for (Point2d pt : l.points()) {
// find nearest with parity one
double tol = lookup.get(pt).size() % 2 == 0 ? highTol : lowTol;
for (Line l2 : getNear(pt, tol)) {
if (!visited.contains(l2) && l2.distance(pt, true) < tol)
queue.add(l2);
}
}
}
currentC++;
}
return out;
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class SolverState method miniPainter.
public ICanPaint miniPainter() {
return new ICanPaint() {
@Override
public void paint(Graphics2D g, PanMouseAdaptor ma) {
// for ( MegaFeatures f : SS.minis.keySet() ) {
//
// for ( MFPoint mfp : SS.minis.get( f ) ) {
// Line l = mfp.image.mega.megafacade;
//
// spreadImages( g, ma, l, mfp, Listz.from( mfp.left, mfp.right ) );
//
// }
// }
// if (SS.minis == null)
int brake = 100;
for (HalfFace f : mesh) {
for (HalfEdge e : f) {
if (e.over != null)
continue;
if (brake-- < 0)
break;
SuperEdge se = (SuperEdge) e;
if (se.mini == null)
continue;
List<MiniFacade> mfs = new ArrayList(se.mini);
// while (mfs .size() < 2)
// mfs.add(null);
spreadImages(g, ma, se.line(), se.line().fromPPram(0.5), mfs);
}
}
int i = 0;
if (minis != null)
for (MegaFeatures f : minis.keySet()) {
// PaintThing.paint (f.megafacade, g, ma);
DumbCluster1D<MFPoint> res = GurobiSkelSolver.clusterMinis(f, minis);
Vector2d dir = f.megafacade.dir();
Vector2d out = new Vector2d(dir);
out.set(-out.y, out.x);
out.scale(ma.toZoom(2) / out.length());
for (Cluster<MFPoint> c : res) {
g.setColor(Rainbow.getColour(i++));
for (MFPoint mfp : c.things) {
Point2d pt = new Point2d(mfp);
pt.add(out);
g.setStroke(new BasicStroke(0.2f));
PaintThing.paint(pt, g, ma);
g.setStroke(new BasicStroke(0.2f));
for (HalfEdge e : GurobiSkelSolver.findNear(f.megafacade, mfp, mesh)) g.drawLine(ma.toX(pt.x), ma.toY(pt.y), ma.toX(e.end.x), ma.toY(e.end.y));
if (mfp.selectedEdge != null) {
g.setStroke(new BasicStroke(2f));
g.drawLine(ma.toX(pt.x), ma.toY(pt.y), ma.toX(mfp.selectedEdge.end.x), ma.toY(mfp.selectedEdge.end.y));
}
}
}
}
g.setStroke(new BasicStroke(1));
}
private void spreadImages(Graphics2D g, PanMouseAdaptor ma, Line sel, Point2d cen, List<MiniFacade> mfs) {
Vector2d perp = sel.dir();
perp.set(-perp.y, perp.x);
perp.normalize();
for (int i = 0; i < mfs.size(); i++) {
MiniFacade mf = mfs.get(i);
Vector2d p2 = new Vector2d(perp);
p2.scale((i + 1) * 10);
p2.add(cen);
if (mf == null) {
g.setColor(Color.black);
g.fillRect(ma.toX(p2.x - 1), ma.toY(p2.y - 3), ma.toZoom(2), ma.toZoom(6));
continue;
}
double w = mf.width * 0.1;
double h = mf.height * 0.1;
mf.paintImage(g, ma, p2.x - w, p2.y - h, p2.x + w, p2.y + h);
}
}
};
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class CompareGens method go.
private void go(SkelGen skelGen, BlockGen blockGen) {
LoopL<Point2d> pts = Loopz.toXZLoop(blockGen.polies);
double[] minMax = Loopz.minMax2d(pts);
double skirt = 20;
minMax[0] -= skirt;
minMax[1] += skirt;
minMax[2] -= skirt;
minMax[3] += skirt;
double sample = 0.25;
int xMin = (int) (minMax[0] / sample), yMin = (int) (minMax[2] / sample), xRange = (int) Math.ceil(minMax[1] / sample) - xMin, yRange = (int) Math.ceil(minMax[3] / sample) - yMin;
double[][] dists = new double[xRange][yRange];
double minD = Double.MAX_VALUE, maxD = -Double.MAX_VALUE;
double mse = 0;
int ptCount = 0;
for (int xi = 0; xi < xRange; xi++) {
System.out.println(xi + "/" + xRange);
for (int yi = 0; yi < yRange; yi++) {
double x = (xi + xMin) * sample;
double y = (yi + yMin) * sample;
Point2d p2d = new Point2d(x, y);
CollisionResults resultsB = new CollisionResults();
blockGen.gNode.collideWith(new Ray(Jme3z.toJmeV(x, 0, y), Jme3z.UP), resultsB);
CollisionResult crB = resultsB.getFarthestCollision();
CollisionResults resultsS = new CollisionResults();
skelGen.gNode.collideWith(new Ray(Jme3z.toJmeV(x, 0, y), Jme3z.UP), resultsS);
CollisionResult crS = resultsS.getFarthestCollision();
if (crB != null && crS != null) {
double dist = Math.abs(crB.getDistance() - crS.getDistance());
minD = Math.min(minD, dist);
maxD = Math.max(maxD, dist);
dists[xi][yi] = dist;
mse += dist * dist;
ptCount++;
} else
dists[xi][yi] = Double.NaN;
}
}
BufferedImage render = new BufferedImage(xRange, yRange, BufferedImage.TYPE_3BYTE_BGR);
WritableRaster raster = render.getRaster();
for (int xi = 0; xi < xRange; xi++) for (int yi = 0; yi < yRange; yi++) {
double d = dists[xi][yi];
if (Double.isNaN(d))
raster.setPixel(xi, yi, new int[] { 0, 0, 0 });
else {
d = (d - minD) / (maxD - minD);
raster.setPixel(xi, yi, colourMap(d));
}
}
double range = 150;
for (int y = 0; y < range; y++) {
for (int x = 0; x < 5; x++) raster.setPixel(x, y, colourMap(y / range));
}
try {
ImageIO.write(render, "png", new File(Tweed.SCRATCH + "distanceMap"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("min : " + minD + "max : " + maxD + " mse: " + (mse / ptCount));
new Show(render);
}
Aggregations