use of org.twak.utils.Line in project chordatlas by twak.
the class Grid method paint.
@Override
public void paint(Graphics2D g, PanMouseAdaptor ma) {
g.setColor(Color.green);
for (Id c : x) {
Line l = new Line(c.value, 0, c.value, 1);
PaintThing.paint(l, g, ma);
}
g.setColor(Color.blue);
for (Map.Entry<Griddable, DRectangle> e : findPositions().entrySet()) {
// DRectangle d2 = new DRectangle( e.getValue() );
// d2.y = d2.y - d2.height;
PaintThing.paint(e.getValue(), g, ma);
}
}
use of org.twak.utils.Line in project chordatlas by twak.
the class Slice method findSupportPoints.
public void findSupportPoints() {
supportPoints.clear();
supportMax = 0;
// Map<Line, Double> totalLineSupport = new HashedMap();
double distSigma = 0.2;
Gaussian distanceG = new Gaussian(0, distSigma), angleG = new Gaussian(0, 0.3);
for (Line l : gis.allLines()) {
double length = l.length();
int noPoints = (int) Math.max(2, length / 0.1);
for (int n = 0; n <= noPoints; n++) {
SupportPoint sp = new SupportPoint(l, l.fromPPram(n / (double) noPoints));
// Double.MAX_VALUE;
sp.support = 0;
for (Line nearL : slice.getNear(sp.pt, distSigma * 3)) {
double angle = nearL.absAngle(sp.line);
// Math.min (sp.pt.distance(line.start), sp.pt.distance(line.end)) ;
double dist = nearL.distance(sp.pt, true);
sp.support += distanceG.value(dist) * angleG.value(angle) * nearL.length();
}
supportPoints.add(sp);
}
}
foundLines = null;
repaint();
}
use of org.twak.utils.Line in project chordatlas by twak.
the class SliceSolver method dataFit.
private static double dataFit(LineSoup filtered, LoopL<Point2d> out) {
if (out.isEmpty() || filtered.all.isEmpty())
return Double.MAX_VALUE;
double totalDist = 0;
for (Line sl : filtered.all) {
double bestDist = Double.MAX_VALUE;
for (Loop<Point2d> loop : out) for (Loopable<Point2d> ll : loop.loopableIterator()) bestDist = Math.min(bestDist, new Line(ll.get(), ll.getNext().get()).distance(sl));
totalDist += bestDist;
}
return totalDist / filtered.all.size();
}
use of org.twak.utils.Line in project chordatlas by twak.
the class GurobiSkelSolver method findNear.
public static List<HalfEdge> findNear(Line l, Point2d start, HalfMesh2 mesh2) {
double tol = 4;
l = new Line(l);
l.moveLeft(tol);
List<HalfEdge> out = new ArrayList<>();
for (HalfFace f : mesh2) try {
for (HalfEdge e : f) {
if (e.end.distanceSquared(start) < tol * tol && l.isOnLeft(e.start) && l.isOnLeft(e.end) && Mathz.inRangeTol(e.line().absAngle(e.next.line()), Mathz.PI2, 1)) {
double angle = l.absAngle(e.line());
if (// regular T-jn on edge or left corner
(e.next.over == null && Mathz.inRangeTol(angle, Mathz.PI2, 1)) || // right corner
(e.over == null && e.next.over == null && angle < 1))
out.add(e);
}
}
} catch (Throwable th) {
th.printStackTrace();
}
return out;
}
use of org.twak.utils.Line in project chordatlas by twak.
the class GurobiSkelSolver method buildMini.
private void buildMini() throws GRBException {
Cache<HalfEdge, GRBLinExpr> isMiniExpr = new Cach<HalfMesh2.HalfEdge, GRBLinExpr>(he -> new GRBLinExpr());
if (minis == null)
return;
for (MegaFeatures mf : minis.keySet()) {
List<MiniPtCluster> clusterVars = new ArrayList<>();
mega2clusters.put(mf, clusterVars);
double mLen = mf.megafacade.length();
DumbCluster1D<MFPoint> clusters = clusterMinis(mf, minis);
for (DumbCluster1D.Cluster<MFPoint> d : clusters) {
// for each cluster, we pick a single MFPoint as the boundary
MiniPtCluster miniPtVar = new MiniPtCluster();
Cache<HalfEdge, GRBLinExpr> isEdgeBind = new Cach<HalfMesh2.HalfEdge, GRBLinExpr>(he -> new GRBLinExpr());
GRBLinExpr selectHE = new GRBLinExpr();
boolean one = false;
for (MFPoint pt : d.things) {
MiniSelectEdge miniSelectEdge = new MiniSelectEdge();
miniPtVar.put(pt, miniSelectEdge);
List<HalfEdge> nearCorners = findNear(mf.megafacade, pt, mesh);
try {
for (HalfEdge he : nearCorners) {
GRBVar heVar = model.addVar(0.0, 1.0, 0, GRB.BINARY, MINI_TO_EDGE);
miniSelectEdge.edge.put(he, heVar);
selectHE.addTerm(1, heVar);
double cost = he.end.distance(pt);
if (he.over != null) {
if (pt.right != null)
cost += Math.abs(pt.right.height - ((SuperFace) he.face).height);
if (pt.left != null)
cost += Math.abs(pt.left.height - ((SuperFace) he.over.face).height);
isEdgeBind.get(he).addTerm(1, heVar);
} else
// bonus for being on a corner;
cost -= totalEdgeLength * 0.1;
target.addTerm(cost, heVar);
isMiniExpr.get(he).addTerm(1, heVar);
one = true;
}
} catch (Throwable th) {
th.printStackTrace();
}
}
if (one) {
clusterVars.add(miniPtVar);
model.addConstr(selectHE, GRB.EQUAL, 1, "pick one near " + d.things.iterator().next());
} else
print("warning skipping minifacade loction " + d.things.size());
for (HalfEdge he : isEdgeBind.cache.keySet()) model.addConstr(isEdgeBind.get(he), GRB.EQUAL, edgeInfo.get(he).isEdge, "minifacade boundary must terminate on edge " + he);
miniPtVar.mean = mf.megafacade.fromPPram(d.mean / mLen);
}
}
double penalty = totalEdgeLength * 0.1;
for (HalfEdge he : edges) {
if (he.over != null && he.next.over == null) {
// edge comes to boundary without minifacade --> penalty
OptionalDouble miniDist = minis.keySet().stream().map(mf -> mf.megafacade).mapToDouble(line -> line.distance(he.end, true)).min();
if (!miniDist.isPresent() || miniDist.getAsDouble() > 4)
continue;
EdgeVars ei = edgeInfo.get(he);
ei.edgeNoMini = model.addVar(0.0, 1.0, 0, GRB.BINARY, EDGE_NO_MINI);
if (isMiniExpr.cache.containsKey(he)) {
ei.isMini = model.addVar(0.0, 1.0, 0, GRB.BINARY, IS_MINI);
GRBLinExpr is = isMiniExpr.get(he);
/* ei.isMini might take 0 or positive integer... assume it's below 10 (0.1 = 1/10) */
model.addConstr(ei.isMini, GRB.LESS_EQUAL, is, "is minifacade on edge " + he);
model.addConstr(scale(0.1, is), GRB.LESS_EQUAL, ei.isMini, "is minifacade on edge " + he);
GRBLinExpr expr = new GRBLinExpr();
expr.addTerm(1, ei.isEdge);
expr.addTerm(1, ei.isMini);
model.addConstr(ei.edgeNoMini, GRB.LESS_EQUAL, expr, null);
expr = new GRBLinExpr();
expr.addTerm(1, ei.edgeNoMini);
expr.addTerm(1, ei.isMini);
model.addConstr(expr, GRB.LESS_EQUAL, 1, null);
expr = new GRBLinExpr();
expr.addTerm(1, ei.isEdge);
expr.addTerm(-1, ei.isMini);
model.addConstr(ei.edgeNoMini, GRB.GREATER_EQUAL, expr, null);
} else {
// no mini, but easier debug
model.addConstr(ei.edgeNoMini, GRB.EQUAL, ei.isEdge, null);
}
target.addTerm(penalty, ei.edgeNoMini);
}
}
}
Aggregations