use of org.twak.utils.Line in project chordatlas by twak.
the class LineSoupPainter method paint.
@Override
public void paint(Object e, Graphics2D g, PanMouseAdaptor ma) {
LineSoup o = (LineSoup) e;
int c = 0;
double scatter = 0.0;
for (Line l : o.all) {
if (o.multiColour)
g.setColor(Rainbow.getColour(c++));
g.drawLine(ma.toX(l.start.x + Math.random() * scatter), ma.toY(l.start.y + Math.random() * scatter), ma.toX(l.end.x + Math.random() * scatter), ma.toY(l.end.y + Math.random() * scatter));
int scale = 1;
if (g.getStroke() instanceof BasicStroke)
scale = (int) ((BasicStroke) g.getStroke()).getLineWidth();
// PaintThing.drawArrow(g, ma, l, scale * 5);
}
}
use of org.twak.utils.Line in project chordatlas by twak.
the class ObjSlice method sliceTri.
public static List<Line> sliceTri(ObjRead mesh, double h, int majorAxis) {
int[] flatAxis = new int[] { (majorAxis + 1) % 3, (majorAxis + 2) % 3 };
if (flatAxis[0] > flatAxis[1]) {
int tmp = flatAxis[0];
flatAxis[0] = flatAxis[1];
flatAxis[1] = tmp;
}
Vector3d sliceNormal = new Vector3d(majorAxis == 0 ? 1 : 0, majorAxis == 1 ? 1 : 0, majorAxis == 2 ? 1 : 0), slicePt = new Vector3d(sliceNormal);
slicePt.scale(h);
LinearForm3D slicePlane = new LinearForm3D(sliceNormal, slicePt);
return slice(mesh, flatAxis, slicePlane, Double.MAX_VALUE, null, Double.MAX_VALUE).stream().map(l -> new Line(l.start.x, l.start.z, l.end.x, l.end.z)).collect(Collectors.toList());
}
use of org.twak.utils.Line in project chordatlas by twak.
the class GISGen method importMesh.
private void importMesh(int index) {
LoopL<Point3d> polies = blocks.get(index);
List<Vector2D> verts = polies.stream().flatMap(ll -> ll.streamAble()).map(x -> {
Line3d l = new Line3d(x.get(), x.getNext().get());
l.move(perp(l.dir(), EXPAND_MESH));
return new Vector2D(l.start.x, l.start.z);
}).collect(Collectors.toList());
double tol = 0.0001;
ConvexHull2D chull = null;
while (tol < 10) {
try {
chull = new MonotoneChain(false, tol).generate(verts);
tol = 1000;
} catch (ConvergenceException e) {
tol *= 10;
}
}
if (chull == null) {
System.out.println("unable to find hull");
return;
}
Loop<Point3d> hull = new Loop<Point3d>((Arrays.stream(chull.getLineSegments()).map(x -> new Point3d(x.getStart().getX(), 0, x.getStart().getY())).collect(Collectors.toList())));
File root = new File(Tweed.SCRATCH + "meshes" + File.separator);
int i = 0;
File l;
while ((l = new File(root, "" + i)).exists()) i++;
l.mkdirs();
File croppedFile = new File(l, CROPPED_OBJ);
boolean found = false;
for (Gen gen : tweed.frame.gens(MiniGen.class)) {
// minigen == optimised obj
((MiniGen) gen).clip(hull, croppedFile);
found = true;
}
if (!found)
for (Gen gen : tweed.frame.gens(MeshGen.class)) {
// obj == just import whole obj
ObjGen objg = (ObjGen) gen;
try {
Files.asByteSource(objg.getFile()).copyTo(Files.asByteSink(croppedFile));
objg.setVisible(false);
found = true;
} catch (IOException e) {
e.printStackTrace();
}
}
if (found) {
Graph2D g2 = new Graph2D();
polies.stream().flatMap(ll -> ll.streamAble()).forEach(x -> g2.add(new Point2d(x.get().x, x.get().z), new Point2d(x.getNext().get().x, x.getNext().get().z)));
g2.removeInnerEdges();
// new Plot (true, g2 );
UnionWalker uw = new UnionWalker();
for (Point2d p : g2.map.keySet()) for (Line line : g2.map.get(p)) uw.addEdge(line.end, line.start);
// new Plot (true, new ArrayList( uw.map.keySet()) );
Loopz.writeXZObj(uw.findAll(), new File(l, "gis.obj"), true);
Loopz.writeXZObj(Loopz.to2dLoop(polies, 1, null), new File(l, "gis_footprints.obj"), false);
BlockGen bg = new BlockGen(l, tweed, polies);
lastMesh.put(index, bg);
tweed.frame.addGen(bg, true);
tweed.frame.setSelected(bg);
} else
JOptionPane.showMessageDialog(tweed.frame(), "Failed to find mesh from minimesh or gml layers");
}
use of org.twak.utils.Line in project chordatlas by twak.
the class GurobiSkelSolver method solve.
public void solve() {
try {
for (HalfFace f : mesh.faces) for (HalfEdge e : f.edges()) {
edges.add(e);
totalEdgeLength += e.length();
}
print("total edge length " + totalEdgeLength);
progress.setProgress((int) (Math.random() * 90));
buildProblem();
model.getEnv().set(GRB.DoubleParam.TimeLimit, GRB.INFINITY);
long time = System.currentTimeMillis();
new Thread(() -> {
while (!gurobiDone) {
try {
Thread.sleep(300);
if ((System.currentTimeMillis() - time) / 1000 > maxTimeSecs) {
print("time's up");
model.terminate();
progress.close();
return;
}
} catch (InterruptedException e1) {
}
progress.setProgress((int) (Math.random() * 90));
if (progress.isCanceled()) {
print("user cancelled");
model.terminate();
}
}
progress.setProgress(100);
}).start();
try {
String file = Tweed.SCRATCH + "problem_" + System.currentTimeMillis() + ".mps";
new File(file).getParentFile().mkdirs();
model.write(file);
model.optimize();
} finally {
gurobiDone = true;
progress.setProgress(100);
}
print("time " + (System.currentTimeMillis() - time) / 1000. + " seconds");
if (model.get(GRB.IntAttr.Status) == GRB.Status.INFEASIBLE) {
print("Can't solve; won't solve");
return;
}
for (HalfFace f : mesh.faces) ((SuperFace) f).classification = index(faceInfo.get(f).color);
if (minis != null)
for (MegaFeatures mf : minis.keySet()) {
if (mega2clusters.containsKey(mf))
for (MiniPtCluster pt : mega2clusters.get(mf)) {
for (Map.Entry<MFPoint, MiniSelectEdge> selectPt : pt.entrySet()) {
for (Map.Entry<HalfEdge, GRBVar> selectEdge : selectPt.getValue().edge.entrySet()) {
if (selectEdge.getValue().get(GRB.DoubleAttr.X) > 0.5) {
HalfEdge e = selectEdge.getKey();
selectPt.getKey().selectedEdge = e;
selectPt.getKey().sameCluster = pt.keySet();
if (e.over != null && e.next.over == null) {
for (MFPoint p : pt.keySet()) ((SuperEdge) e.next).addMini(p.right);
for (MFPoint p : pt.keySet()) ((SuperEdge) e.over.findBefore()).addMini(p.left);
}
if (e.over == null && e.next.over == null) {
Line parallel = selectPt.getKey().mega.megafacade;
if (parallel.absAngle(e.line()) < parallel.absAngle(e.next.line()))
for (MFPoint p : pt.keySet()) ((SuperEdge) e).addMini(p.left);
else
for (MFPoint p : pt.keySet()) ((SuperEdge) e.next).addMini(p.right);
}
}
}
}
}
}
if (false)
for (HalfEdge he : edges) {
if (he.over != null && he.next.over == null) {
// face comes to boundary
boolean viz = false;
EdgeVars ei = edgeInfo.get(he);
if (ei.edgeNoMini != null) {
viz = true;
}
if (viz)
PaintThing.debug.put("dd", new Point2d(he.end));
}
}
if (globalProfs != null)
for (HalfEdge e : edges) {
EdgeVars ei = edgeInfo.get(e);
GRBVar plot = ei.debug;
if (plot != null) {
// && plot.get(GRB.DoubleAttr.X) > 0.5 ) {
Point2d o = new Point2d(e.end);
PaintThing.debug.put(1, o);
}
int p = index(ei.profile);
((SuperEdge) e).profI = p;
((SuperEdge) e).prof = p < 0 ? null : globalProfs.get(p);
}
dumpModelStats(edges);
model.getEnv().dispose();
model.dispose();
} catch (GRBException e) {
print("Error code: " + e.getErrorCode() + ". " + e.getMessage());
e.printStackTrace();
}
}
use of org.twak.utils.Line in project chordatlas by twak.
the class GurobiSkelSolver method notBoth.
private void notBoth(HalfEdge e1, HalfEdge e2, boolean isContraint, double badThingsAreBad) throws GRBException {
GRBLinExpr no = new GRBLinExpr();
no.addTerm(1, edgeInfo.get(e1).isEdge);
no.addTerm(1, edgeInfo.get(e2).isEdge);
if (isContraint) {
model.addConstr(no, GRB.LESS_EQUAL, 1, "bad geom < 1");
} else {
GRBVar bothSelected = model.addVar(0.0, 1.0, 0, GRB.BINARY, BAD_GEOM);
no.addTerm(-2, bothSelected);
model.addConstr(no, GRB.LESS_EQUAL, 1, "bad geom <");
model.addConstr(no, GRB.GREATER_EQUAL, -0.5, "bad geom >");
target.addTerm(badThingsAreBad, bothSelected);
{
Line l1 = e1.line(), l2 = e2.line();
l1.start = new Point2d(l1.start);
l1.end = new Point2d(l1.end);
l2.start = new Point2d(l2.start);
l2.end = new Point2d(l2.end);
l1.moveLeft(-0.1);
l2.moveLeft(-0.1);
PaintThing.debug(new Color(255, 170, 0), 2, l1);
PaintThing.debug(new Color(170, 0, 255), 2, l2);
edgeInfo.get(e1).debug = bothSelected;
}
}
}
Aggregations