use of javax.vecmath.Point2d in project chordatlas by twak.
the class ImagePlaneGen method rotateByAngle.
public ImagePlaneGen rotateByAngle(double deltaAngle, double distance) {
Line nLine = new Line(new Point2d(a.x, a.z), new Point2d(b.x, b.z));
Point2d cen = nLine.fromPPram(0.5);
double angle = nLine.aTan2() + deltaAngle;
double len = nLine.length() / 2;
Vector2d dir = new Vector2d(-Math.cos(angle) * len, -Math.sin(angle) * len);
Point2d start = new Point2d(cen), end = new Point2d(cen);
start.add(dir);
end.sub(dir);
ImagePlaneGen out = new ImagePlaneGen(this);
out.a.set((float) start.x, a.y, (float) start.y);
out.b.set((float) end.x, b.y, (float) end.y);
out.calcUV();
return out;
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class ImagePlaneGen method render.
public BufferedImage render(File folder, float scale, Pano pano, Line mega, String filename) {
Point3d worldPos = new Point3d();
Vector3d worldNormal = new Vector3d(), planeNormal = new Vector3d(Jme3z.from(b));
planeNormal.sub(Jme3z.from(a));
planeNormal.normalize();
planeNormal.set(planeNormal.z, 0, -planeNormal.x);
BufferedImage out = new BufferedImage((int) (a.distance(b) * scale), (int) ((heightMax - heightMin) * scale), BufferedImage.TYPE_3BYTE_BGR);
BufferedImage outClip;
if (DO_MASK)
outClip = new BufferedImage(out.getWidth(), out.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
BufferedImage source = pano.getRenderPano();
for (int x = 0; x < out.getWidth(); x++) {
for (int y = 0; y < out.getHeight(); y++) {
float[] planeWorld = uvToWorld(x / (float) out.getWidth(), 1 - (y / (float) out.getHeight()));
int c = pano.castTo(planeWorld, source, worldPos, worldNormal);
out.setRGB(x, y, c);
if (DO_MASK) {
Color d = Color.white;
if (Double.isNaN(worldPos.x) || (mega != null && mega.distance(new Point2d(worldPos.x, worldPos.z), true) > 5))
d = Color.black;
outClip.setRGB(x, y, d.getRGB());
}
}
if (x % 100 == 0)
System.out.println(x + " / " + out.getWidth());
}
System.out.println("render complete!");
if (folder != null)
try {
ImageIO.write(out, "png", new File(folder, filename + ".png"));
if (DO_MASK)
ImageIO.write(outClip, "png", new File(folder, "mask.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
return out;
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class GBias method getAngle.
/**
* local bias
*/
public Double getAngle(Line line, Point2d cen) {
final double PI8 = Math.PI / 8;
DRectangle r = new DRectangle(line);
r.grow(expand);
Collection<Longer> res = tree.queryRange(r);
double bestScore = -Double.MAX_VALUE;
Double bestAngle = null;
for (AxisAlignedBoundingBox aabb : res) {
Line gis = ((Longer) aabb).line;
double len = gis.length();
// gis.distance( line );
double dist = gis.fromPPram(0.5).distance(line.fromPPram(0.5));
if (dist < len * expand) {
double angle = line.absAngle(gis);
if (angle < PI8) {
double score = (PI8 - angle) / dist;
if (score > bestScore) {
bestAngle = gis.aTan2();
bestScore = score;
}
} else if (Mathz.inRangeTol(angle, Mathz.PI2, PI8)) {
double score = 0.2 * (PI8 - angle) / dist;
if (score > bestScore) {
gis = new Line(new Point2d(gis.start.y, -gis.start.x), new Point2d(gis.end.y, -gis.end.x));
if (gis.absAngle(line) > PI8)
gis = gis.reverse();
bestAngle = gis.aTan2();
bestScore = score;
}
}
}
}
if (bestAngle != null)
return bestAngle;
else
return null;
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class Concarnie method apply.
private List<Problem> apply(Problem problem, int count) {
if (depth > 10 || problem.soup.isEmpty()) {
problem.addPortal();
return Collections.emptyList();
}
Set<Line> portals = new HashSet<>();
Set<Line> in = new HashSet<>(problem.soup);
for (Line sl : problem.hull) {
RangeMerge<Line> rm = new RangeMerge<>(P.CON_TOL, P.CON_TOL);
LinearForm lf = new LinearForm(sl);
for (Line l : problem.soup) {
if (onHull(sl, l)) {
double pps = lf.findPParam(l.start), ppe = lf.findPParam(l.end);
rm.add(pps, ppe, l);
in.remove(l);
}
}
List<Double> rmGet = rm.get();
if (rmGet.isEmpty()) {
if (!sl.start.equals(sl.end)) {
if (Double.isNaN(sl.start.x))
System.out.println("help!");
// whole thing is portal
portals.add(sl);
}
} else {
List<Point2d> occupied = new ArrayList();
{
double lf1 = lf.findPParam(sl.start), lf2 = lf.findPParam(sl.end);
if (lf1 > lf2) {
double tmp = lf1;
lf1 = lf2;
lf2 = tmp;
}
for (double d : rmGet) {
d = Mathz.clamp(d, lf1, lf2);
occupied.add(lf.fromPParam(d));
}
}
boolean onHull = false;
{
Point2d snapE = occupied.get(0), snapS = occupied.get(occupied.size() - 1);
if (snapS.distance(sl.start) < P.CON_TOL)
snapS.set(sl.start);
else {
occupied.add(new Point2d(sl.start));
}
if (snapE.distance(sl.end) < P.CON_TOL)
snapE.set(sl.end);
else {
occupied.add(0, new Point2d(sl.end));
onHull = true;
}
}
for (Pair<Point2d, Point2d> pair : new ConsecutiveItPairs<Point2d>(occupied)) {
onHull = !onHull;
if (pair.first().equals(pair.second()))
continue;
Line line = new Line(pair.first(), pair.second());
if (onHull) {
if (depth % 2 == 0)
line = line.reverse();
graph.add(line);
} else {
portals.add(line.reverse());
}
}
}
}
if (in.size() == problem.soup.size()) {
// we didn't do anything! remove something, anything...
List<Line> d = new ArrayList(in);
Collections.sort(d, (a, b) -> Double.compare(a.length(), b.length()));
for (// remove the shortest 1/3 lines
int i = 0; // remove the shortest 1/3 lines
i < Math.max(1, in.size() * 0.33); // remove the shortest 1/3 lines
i++) in.remove(d.get(i));
}
List<Portal> mergedPortals = mergeConsecutive(portals);
// assign each member of in to a portal
MultiMapSet<Portal, Line> subproblems = new MultiMapSet();
if (!mergedPortals.isEmpty()) {
// O(n^3) closest-clique assignment
MultiMapSet<Portal, Line> sub2 = new MultiMapSet();
for (Portal p : mergedPortals) sub2.putAll(p, p.lines);
while (!in.isEmpty()) {
double bestDist = Double.MAX_VALUE;
Portal bestP = null;
Line bestL = null;
for (Line l : in) for (Portal p : sub2.keySet()) for (Line sl : sub2.get(p)) {
double dlsl = l.distance(sl);
if (// ignore lines a long way away
dlsl > Math.max(P.CON_TOL * 3, p.length * 0.5))
continue;
double dist = dlsl + 0.1 * l.distance(p.summary);
if (dist < bestDist) {
bestP = p;
bestDist = dist;
bestL = l;
}
}
if (bestL == null)
break;
in.remove(bestL);
double lenBestL = bestL.length();
if (lenBestL > P.CON_TOL && lenBestL > 0.5 * bestP.summary.length()) {
in.add(new Line(bestL.start, bestL.fromPPram(0.5)));
in.add(new Line(bestL.fromPPram(0.5), bestL.end));
} else {
subproblems.put(bestP, bestL);
sub2.put(bestP, bestL);
}
}
} else {
mergedPortals.add(null);
subproblems.putAll(null, in);
}
return mergedPortals.stream().map(x -> new Problem(x == null ? Collections.emptyList() : x.lines, subproblems.get(x))).collect(Collectors.toList());
}
use of javax.vecmath.Point2d in project chordatlas by twak.
the class Concarnie method project.
public static Point2d project(Line l, Point2d pt) {
Vector2d v1 = new Vector2d(l.end);
v1.sub(l.start);
Vector2d v2 = new Vector2d(pt);
v2.sub(l.start);
double param = v2.dot(v1) / v1.length();
if (param < 0 || param > v1.length())
return null;
v1.normalize();
v1.scale(param);
v1.add(l.start);
return new Point2d(v1);
}
Aggregations