use of javax.vecmath.Point2d in project chordatlas by twak.
the class Slice method capAtHeight.
public static void capAtHeight(ObjDump out, LoopL<Point2d> slice, boolean flipNormals, double height) {
double[] normal = new double[] { 0, flipNormals ? 1 : -1, 0 };
final float[] up = new float[] { 0, 1, 0 };
for (Loop<Point2d> loop : slice) {
List<Float> coords = new ArrayList();
List<Integer> inds = new ArrayList();
for (Point2d pt : loop) {
inds.add(inds.size());
coords.add((float) pt.x);
coords.add((float) height);
coords.add((float) pt.y);
}
float[] p = Arrayz.toFloatArray(coords);
int[] i = Arrayz.toIntArray(inds), ti = new int[i.length * 3];
int tris = EarCutTriangulator.triangulateConcavePolygon(p, 0, inds.size(), i, ti, up);
for (int t = 0; t < tris; t++) {
List<double[]> pts = new ArrayList<>(), norms = new ArrayList<>();
for (int j : flipNormals ? new int[] { 0, 1, 2 } : new int[] { 2, 1, 0 }) {
int k = ti[t * 3 + j];
pts.add(new double[] { p[k * 3 + 0], p[k * 3 + 1], p[k * 3 + 2] });
norms.add(normal);
}
out.addFace(pts.toArray(new double[pts.size()][]), null, norms.toArray(new double[norms.size()][]));
}
// for (Point2d pt : loop) {
// pts.add(new double[] {pt.x, height, pt.y } );
// norms.add(up);
// }
//
// if (!flipNormals)
// Collections.reverse(pts);
}
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class Slice method extrude.
public static void extrude(ObjDump out, LoopL<Point2d> slice, double h1, double h2) {
for (Loop<Point2d> loop : slice) {
for (Loopable<Point2d> pt : loop.loopableIterator()) {
List<double[]> pts = new ArrayList<>(), norms = new ArrayList<>();
Point2d a = pt.get(), b = pt.getNext().get();
pts.add(new double[] { a.x, h1, a.y });
pts.add(new double[] { b.x, h1, b.y });
pts.add(new double[] { b.x, h2, b.y });
pts.add(new double[] { a.x, h2, a.y });
Vector2d d = new Vector2d(b);
d.sub(a);
d.normalize();
double[] norm = new double[] { -d.y, 0, d.x };
for (int i = 0; i < 4; i++) norms.add(norm);
out.addFace(pts.toArray(new double[pts.size()][]), null, norms.toArray(new double[norms.size()][]));
}
}
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class FRect method mouseDown.
@Override
public void mouseDown(MouseEvent e, PanMouseAdaptor ma) {
double best = ma.fromZoom(10);
dragging = null;
Point2d pt = lastPoint = flip(ma.from(e));
for (Bounds b : new Bounds[] { XMIN, YMIN, XMAX, YMAX }) {
double dist = getEdge(b).distance(pt);
if (dist < best) {
best = dist;
dragging = b;
}
}
// dragging == null means move whole rect
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class GreebleGrid method createBalcony.
protected void createBalcony(DRectangle balc, Matrix4d to3d, MeshBuilder mat, double _depth) {
Point2d[] pts = balc.points();
Point3d[] ptt = new Point3d[4];
Vector3f[] ptf = new Vector3f[4];
for (int i = 0; i < 4; i++) {
ptt[i] = Pointz.to3(pts[i]);
to3d.transform(ptt[i]);
ptf[i] = Jme3z.to(ptt[i]);
}
Vector3f along = ptf[3].subtract(ptf[0]);
along.normalizeLocal();
Vector3f up = ptf[1].subtract(ptf[0]);
up.normalizeLocal();
Vector3f out = along.cross(up);
Vector3f loc = ptf[0];
float bg = 0.08f, sm = 0.03f, height = balc.heightF(), depth = (float) _depth, width = balc.widthF(), spacing = 0.3f, bgsm = (bg - sm) / 2;
// floor
mat.addCube(loc, up, along, out, bg, width, (float) depth);
// top railings
mat.addCube(loc.add(up.mult(height)), up, along, out, bg, bg, depth);
mat.addCube(loc.add(up.mult(height).add(along.mult(width - bg))), up, along, out, bg, bg, depth);
mat.addCube(loc.add(up.mult(height).add(out.mult(depth - bg))), up, along, out, bg, width, bg);
int count = (int) (depth / spacing);
// side decorations
for (int c = 0; c < count + 1; c++) {
mat.addCube(loc.add(out.mult(c * spacing)).add(along.mult(bgsm)), up, along, out, height, sm, sm);
mat.addCube(loc.add(out.mult(c * spacing)).add(along.mult(width - sm - bgsm)), up, along, out, height, sm, sm);
}
count = (int) (width / spacing);
spacing = (width - sm - 2 * bgsm) / count;
// top decorations
for (int c = 0; c < count + 1; c++) {
mat.addCube(loc.add(out.mult(depth - sm - bgsm)).add(along.mult(bgsm + spacing * c)), up, along, out, height, sm, sm);
}
}
use of javax.vecmath.Point2d 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;
}
Aggregations