use of org.apache.commons.math3.geometry.euclidean.twod.Vector2D in project graphysica by Graphysica.
the class RepereTest method testPositionsReelles.
@Test
public void testPositionsReelles() {
assertEquals(new Vector2D(-2, -2), repere.positionReelle(new Vector2D(500 - 2 * 50, 500 + 2 * 50)));
assertEquals(new Vector2D(-2, -1), repere.positionReelle(new Vector2D(500 - 2 * 50, 500 + 50)));
assertEquals(new Vector2D(-1, -2), repere.positionReelle(new Vector2D(500 - 50, 500 + 2 * 50)));
assertEquals(new Vector2D(-1, -1), repere.positionReelle(new Vector2D(500 - 50, 500 + 50)));
assertEquals(new Vector2D(-1, 0), repere.positionReelle(new Vector2D(500 - 50, 500)));
assertEquals(new Vector2D(0, -1), repere.positionReelle(new Vector2D(500, 500 + 50)));
assertEquals(new Vector2D(0, 0), repere.positionReelle(new Vector2D(500, 500)));
assertEquals(new Vector2D(0, 1), repere.positionReelle(new Vector2D(500, 500 - 50)));
assertEquals(new Vector2D(1, 0), repere.positionReelle(new Vector2D(500 + 50, 500)));
assertEquals(new Vector2D(1, 1), repere.positionReelle(new Vector2D(500 + 50, 500 - 50)));
assertEquals(new Vector2D(1, 2), repere.positionReelle(new Vector2D(500 + 50, 500 - 2 * 50)));
assertEquals(new Vector2D(2, 1), repere.positionReelle(new Vector2D(500 + 2 * 50, 500 - 50)));
assertEquals(new Vector2D(2, 2), repere.positionReelle(new Vector2D(500 + 2 * 50, 500 - 2 * 50)));
}
use of org.apache.commons.math3.geometry.euclidean.twod.Vector2D in project chordatlas by twak.
the class Prof method parameterize.
public static // all profs from a single profile-edge are in the same 2D space, with strange x-origin
Prof parameterize(// all profs from a single profile-edge are in the same 2D space, with strange x-origin
List<Prof> in) {
// double toProfileEdge;
// {
// Prof eg = in.iterator().next();
// Point3d p = Pointz.to3( profileEdge.start );
// toProfileEdge = eg.to2d( p ).x;
// }
double avgMinY = in.stream().filter(p -> p != null).mapToDouble(p -> p.get(0).y).average().getAsDouble();
Set<Line> lines = new HashSet<>();
for (Prof p : in) for (int i = 1; i < p.size(); i++) lines.add(new Line(p.get(i - 1), p.get(i)));
SliceParameters P = new SliceParameters(5);
P.FL_REGRESS = true;
P.FL_BINS = 20;
// double A = 0.4; // simple = 0.4
// double B = 0.1; // simple = 1;
// simple = 0.4
double A = 0.2;
// simple = 0.1;
double B = 0.3;
// simple = 0.1; rotate threshold, radians
double C = 0.1;
double firstFloorHeight = 2;
P.MIN_LINES = Math.max(1, in.size() * A);
lines = new FindLines(lines, P) {
protected double nextAngle(Set<Line> remaining, int iteration) {
double delta = Math.PI / P.FL_BINS;
// angle bin
Bin<Line> aBin = new Bin(-Math.PI - delta, Math.PI + delta, P.FL_BINS * 2, true);
for (Line l : remaining) {
double len = l.length();
double angle = l.aTan2();
aBin.add(angle, len, l);
}
// return MUtils.PI2;
if (iteration < 1 && aBin.getWeight(Mathz.PI2) >= 10)
return Mathz.PI2;
int aBinI = aBin.maxI();
return aBin.val(aBinI);
}
protected double getTolNearLine(Point2d p) {
return P.FL_NEAR_LINE * (p.y < avgMinY + firstFloorHeight ? 5 : B);
}
protected double getTolNearLine2(Point2d p) {
return P.FL_NEAR_LINE_2 * (p.y < avgMinY + firstFloorHeight ? 10 : B);
}
protected double getTolRemoveAngle(Line l) {
return l.start.y < avgMinY + firstFloorHeight ? Math.PI * 0.5 : Math.PI * 0.2;
}
}.result.all;
List<Line> llines = // is rubbish
lines.stream().filter(l -> l.lengthSquared() > 0.001).filter(// is floor polygon
l -> l.end.y > avgMinY + 1 || Math.abs(l.start.y - l.end.y) > 0.1).collect(Collectors.toList());
Prof clean = new Prof(in.get(in.size() / 2));
clean.clear();
if (llines.isEmpty()) {
clean.add(new Point2d(0, 0));
clean.add(new Point2d(0, 1));
return clean;
}
for (int i = 0; i < llines.size(); i++) {
Line l = llines.get(i);
double angle = l.aTan2();
if (angle < Mathz.PI2 + C && angle > Mathz.PI2 - C)
llines.set(i, FindLines.rotateToAngle(l, l.fromPPram(0.5), Mathz.PI2));
}
// llines.stream().filter( l -> l.start.y > l.end.y ).forEach( l -> l.reverseLocal() );
Collections.sort(llines, new Comparator<Line>() {
public int compare(Line o1, Line o2) {
return Double.compare(o1.fromPPram(0.2).y, o2.fromPPram(0.2).y);
}
});
// for (Line l : llines)
// PaintThing.debug( new Color(170,0,255), 2f, new Line( l.start.x+5, -l.start.y, l.end.x+5, -l.end.y ) );
Line lastL = null;
Point2d lastP = new Point2d(0, -Double.MAX_VALUE);
for (Line l : llines) {
// if (c >= 6)
// continue;
// if ( c== 5)
// System.out.println("here");
// c++;
Point2d mid = l.fromPPram(0.5);
if (!(lastL != null && !lastL.isOnLeft(mid) || (lastP.y == -Double.MAX_VALUE || (mid.y >= lastP.y - 0.5 && mid.x <= lastP.x + 0.5))))
continue;
boolean startAbove = l.start.y >= lastP.y && l.start.x <= lastP.x, endAbove = l.end.y >= lastP.y && l.end.x <= lastP.x;
if (l.end.y < l.start.y)
l.end.y = l.start.y;
if (startAbove && endAbove) {
// okay
} else {
if (lastL != null && l.start.distanceSquared(lastP) < 9) {
Point2d sec = lastL.intersects(l, false);
if (sec != null && sec.distanceSquared(lastP) < 9 && sec.x <= lastL.start.x && sec.y >= lastL.start.y) {
clean.remove(clean.size() - 1);
clean.add(sec);
lastP = sec;
l.start = sec;
} else if (l.start.x < lastP.x) {
sec = new LinearForm(new Vector2d(1, 0)).findC(l.start).intersect(new LinearForm(lastL));
if (sec != null && sec.distanceSquared(lastP) < 9) {
clean.remove(clean.size() - 1);
clean.add(sec);
lastP = sec;
}
}
}
if (l.start.x > lastP.x + 0.01 || l.end.x > lastP.x + 0.01) {
Point2d sec = new LinearForm(new Vector2d(0, 1)).findC(new Point2d(lastP.x, 0)).intersect(new LinearForm(l));
if (sec != null && sec.distanceSquared(lastP) < 9 && sec.distanceSquared(l.start) < 9) {
if (l.start.x > lastP.x)
l.start = sec;
else
l.end = sec;
}
}
}
if (lastL != null && l.start.distanceSquared(lastP) < 4) {
Point2d sec = lastL.intersects(l, false);
if (sec != null && (sec.distanceSquared(lastP) < 4 || Math.abs(sec.y - lastP.y) < 1) && sec.x <= lastL.start.x && sec.y >= lastL.start.y) {
clean.remove(clean.size() - 1);
clean.add(sec);
lastP = sec;
l.start = sec;
} else if (l.start.x < lastP.x) {
sec = new LinearForm(new Vector2d(1, 0)).findC(l.start).intersect(new LinearForm(lastL));
if (sec != null && (sec.distanceSquared(lastP) < 4 || Math.abs(sec.y - lastP.y) < 1)) {
clean.remove(clean.size() - 1);
clean.add(sec);
lastP = sec;
// l.start = sec;
}
}
}
if (lastP.y - l.end.y < 3 && l.end.x - lastP.x < 3) {
for (Point2d pt : l.points()) {
pt.x = Math.min(pt.x, lastP.x);
pt.y = Math.max(pt.y, lastP.y);
}
if (!l.start.equals(l.end))
for (Point2d pt : l.points()) {
// if (c == 2)
// PaintThing.debug.put(1, new Point2d ( pt.x, -pt.y ) );
pt = new Point2d(pt);
pt.x = Math.min(pt.x, lastP.x);
pt.y = Mathz.max(0, pt.y, lastP.y);
if (clean.isEmpty() && pt.y > 0.2) {
clean.add(new Point2d(pt.x, 0));
}
if (lastP != null && pt.distanceSquared(lastP) > 0.02) {
clean.add(pt);
}
lastP = clean.get(clean.size() - 1);
if (clean.size() >= 3) {
Point2d a = clean.get(clean.size() - 1), b = clean.get(clean.size() - 2), c = clean.get(clean.size() - 3);
if (Math.abs(Mathz.area(c, b, a)) < 0.1 || Mathz.absAngleBetween(a, b, c) < 0.1)
clean.remove(clean.size() - 2);
}
}
}
if (clean.size() >= 2)
lastL = new Line(clean.get(clean.size() - 2), clean.get(clean.size() - 1));
}
return clean;
}
use of org.apache.commons.math3.geometry.euclidean.twod.Vector2D in project chordatlas by twak.
the class SkelFootprint method cleanFootprints.
private static void cleanFootprints(HalfMesh2 mesh) {
for (HalfFace hf : mesh.faces) for (HalfEdge e : hf.edges()) if (e.over != null && e.over.face != e.face)
e.over = null;
Map<HalfEdge, Double> mergePoint = new HashMap();
Predicate<HalfEdge> badEdges = new Predicate<HalfMesh2.HalfEdge>() {
@Override
public boolean test(HalfEdge t) {
if (// is edge within a single face
t.over != null)
// preserve as hole-marker
return false;
double len = t.length();
if (t.length() < 0.2) {
mergePoint.put(t, 0.5);
return true;
}
double angleNext = t.line().absAngle(t.next.line());
final double tol = 0.1;
if (t.next.over == null && len < t.next.length() && angleNext > Math.PI - tol) {
mergePoint.put(t, 0.);
return true;
}
if (t.next.over == null && angleNext < tol) {
mergePoint.put(t, 0.);
return true;
}
HalfEdge prev = t.findBefore();
double anglePrev = t.line().absAngle(prev.line());
if (prev.over == null && len <= prev.length() && anglePrev > Math.PI - tol) {
mergePoint.put(t, 1.);
return true;
}
if (prev.over == null && anglePrev < tol) {
mergePoint.put(t, 1.);
return true;
}
return false;
}
};
f: for (HalfFace f : new ArrayList<>(mesh.faces)) {
Set<HalfEdge> togo = Streamz.stream(f.edges()).filter(badEdges).collect(Collectors.toSet());
while (!togo.isEmpty()) {
HalfEdge g = togo.iterator().next(), p = g.findBefore(), n = g.next;
togo.remove(g);
togo.remove(p);
togo.remove(n);
if (g.replaceByPoint(mesh, g.line().fromPPram(mergePoint.get(g))))
continue f;
HalfEdge pp = p.findBefore();
Streamz.stream(pp, p, n, n.next).forEach(o -> togo.remove(o));
Streamz.stream(pp, p, n, n.next).filter(badEdges).forEach(e -> togo.add(e));
}
}
for (HalfFace f : mesh.faces) {
Set<Point2d> seen = new HashSet<>();
for (HalfEdge e : f) {
if (seen.contains(e.end) && e.over == null && e.next.over == null) {
HalfEdge n = e.next;
Point2d edited;
Vector2d b4 = e.line().dir(), af = n.line().dir();
b4.normalize();
af.normalize();
b4.set(b4.y, -b4.x);
af.set(af.y, -af.x);
b4.add(af);
b4.scale(1 / b4.length());
edited = new Point2d(b4);
edited.add(e.end);
n.start = edited;
e.end = new Point2d(edited);
}
seen.add(e.end);
}
}
}
use of org.apache.commons.math3.geometry.euclidean.twod.Vector2D in project graphysica by Graphysica.
the class MainApp method ajouterObjetsEspace.
private void ajouterObjetsEspace() {
espace.ajouter(new Point(Vector2D.ZERO));
espace.ajouter(new Point(new Vector2D(4, 8)));
espace.ajouter(new SegmentDroite(new Point(Vector2D.ZERO), new Point(new Vector2D(4, 8))));
}
use of org.apache.commons.math3.geometry.euclidean.twod.Vector2D in project graphysica by Graphysica.
the class EspaceInteractif method zoomer.
/**
* Zoome l'espace de la toile vers la position définie du curseur. Un zoom a
* lieu si le défilement vertical est positif, un dézoom a lieu si le
* défilement vertical est négatif, et aucun zoom n'a lieu si le défilement
* vertical est nul.
*
* @param defilementVertical le défilement vertical du zoom.
* @param positionCurseur la position virtuelle du curseur sur la toile.
*/
private void zoomer(final double defilementVertical, @NotNull final Vector2D positionCurseur) {
if (defilementVertical != 0) {
final Vector2D translationOrigine = positionCurseur.subtract(repere.getOrigineVirtuelle());
repere.setOrigineVirtuelle(repere.getOrigineVirtuelle().add(translationOrigine));
double facteurZoom = FACTEUR_ZOOM;
if (defilementVertical < 0) {
facteurZoom = 1 / FACTEUR_ZOOM;
}
repere.setEchelle(repere.getEchelle().scalarMultiply(facteurZoom));
final Vector2D nouvelleOrigine = repere.getOrigineVirtuelle().subtract(translationOrigine.scalarMultiply(facteurZoom));
repere.setOrigineVirtuelle(new Vector2D((int) nouvelleOrigine.getX(), (int) nouvelleOrigine.getY()));
}
}
Aggregations