I have a List<Coordinate> which represents a route.
I want to simplify it using JTS.
I saw few method but I wasn't sure which one will fit my needs the best:
1) how can I convert my coordinate to geometry (line?)
TopologyPreservingSimplifier(Geometry inputGeom)
void setDistanceTolerance(double distanceTolerance)
Geometry getResultGeometry()
2)
DouglasPeuckerLineSimplifier(Coordinate[] pts)
void setDistanceTolerance(double distanceTolerance)
Coordinate[] simplify()
static Coordinate[] simplify(Coordinate[] pts, double distanceTolerance)
3) maybe this?
TopologyPreservingSimplifier.simplify(geom, threshold-in-degrees-that-depends-on-the-length);
To simplify a line you first have to have one. So first build your LineString using the createLineString(Coordinate[]) method of a GeometryFactory instance.
Then just use the DouglasPeuckerSimplifier (you don't need to preserve topology for just one line, the start and end points are all the topology there and they won't be changed). You will have to cast the result to a LineString again if you want to use it as such later on. And you will have to choose an appropriate tolerance.
LineString lss = (LineString) DouglasPeuckerSimplifier.simplify(ls, tolerance);
Related
I'm trying to make some sort of 3D editor, and I'm trying to make an "orbit" tool, much like the one in Blender.
Now I'd like to know what the angle is. I used the code provided by José Pereda that can be found here, but I need the angles to be in the range from 0 to 2π. I cannot retrieve them from the acquired angles since the output values don't range from -π to π and are different for every output.
Also, the extracted angles need to be relative to each other, much like if you put 3 different Rotate transformations where every following one is relative to the preceding ones, preferably in YXZ order, since that's the order I use everywhere else, as well as the model format the editor is going to export into.
As requested, I have uploaded the part of the code that is relevant to the question on Pastebin. As far as I could tell from the printed values, the angles are relative to each other in XYZ order. For angle calculation, I use the snippet from the linked question:
public static Vec3d getAngle(Node n) {
Transform T = n.getLocalToSceneTransform();
double roll = Math.atan2(-T.getMyx(), T.getMxx());
double pitch = Math.atan2(-T.getMzy(), T.getMzz());
double yaw = Math.atan2(T.getMzx(), Math.sqrt(T.getMzy() * T.getMzy() + T.getMzz() * T.getMzz()));
return new Vec3d(roll, pitch, yaw);
}
Just a quick notice, I have very little knowledge of matrices and their transformations, since that's something we'll be taking in our school next year, which makes it harder for me to understand.
So I'm programming a recursive program that is supposed to draw Koch's snowflake using OpenGL, and I've got the program basically working except one tiny issue. The deeper the recursion, the weirder 2 particular vertices get. Pictures at the bottom.
EDIT: I don't really care about the OpenGL aspect, I've got that part down. If you don't know OpenGL, all that the glVertex does is draw a line between the two vertices specified in the 2 method calls. Pretend its drawLine(v1,v2). Same difference.
I suspect that my method for finding points is to blame, but I can't find anything that looks incorrect.
I'm following the basically standard drawing method, here are the relevant code snips
(V is for vertex V1 is the bottom left corner, v2 is the bottom right corner, v3 is the top corner):
double dir = Math.PI;
recurse(V2,V1,n);
dir=Math.PI/3;
recurse(V1,V3,n);
dir= (5./3.)* Math.PI ;
recurse(V3,V2,n);
Recursive method:
public void recurse(Point2D v1, Point2D v2, int n){
double newLength = v1.distance(v2)/3.;
if(n == 0){
gl.glVertex2d(v1.getX(),v1.getY());
gl.glVertex2d(v2.getX(),v2.getY());
}else{
Point2D p1 = getPointViaRotation(v1, dir, newLength);
recurse(v1,p1,n-1);
dir+=(Math.PI/3.);
Point2D p2 = getPointViaRotation(p1,dir,newLength);
recurse(p1,p2,n-1);
dir-=(Math.PI*(2./3.));
Point2D p3 = getPointViaRotation(p2, dir, newLength);
recurse(p2,p3,n-1);
dir+=(Math.PI/3.);
recurse(p3,v2,n-1);
}
}
I really suspect my math is the problem, but this looks correct to me:
public static Point2D getPointViaRotation(Point2D p1, double rotation, double length){
double xLength = length * Math.cos(rotation);
double yLength = length * Math.sin(rotation);
return new Point2D.Double(xLength + p1.getX(), yLength + p1.getY());
}
N = 0 (All is well):
N = 1 (Perhaps a little bendy, maybe)
N = 5 (WAT)
I can't see any obvious problem code-wise. I do however have a theory about what happens.
It seems like all points in the graph are based on the locations of the points that came before it. As such, any rounding errors that occurs during this process eventually start accumulating, eventually ending with it going haywire and being way off.
What I would do for starters is calculating the start and end points of each segment before recursing, as to limit the impact of the rounding errors of the inner calls.
One thing about Koch's snowflake is, that the algorithm will lead to a rounding issue one time (it is recursive and all rounding errors add up). The trick is, to keep it going as long as possible. There're three things you can do:
If you want to get more detailed, the only way is to expand the possibilities of Double. You will need to use your own range of coordinates and transform them, every time you actually paint on the screen, to screen coordinates. Your own coordinates should zoom and show the last recursion step (the last triangle) in a coordination system of e.g. 100x100. Then calculate the three new triangles on top of that, transform into screen coordinates and paint.
The line dir=Math.PI/3; divides by 3 instead of (double) 3. Add the . after the 3
Make sure you use Point2D.Double anywhere. Your code should do so, but I would explicitely write it everywhere.
You won the game, when you still have a nice snowflake but get a Stackoverflow.
So, it turns out I am the dumbest man alive.
Thanks everyone for trying, I appreciate the help.
This code is meant to handle an equilateral triangle, its very specific about that (You can tell by the angles).
I put in a triangle with the height equal to the base (not equilateral). When I fixed the input triangle, everything works great.
I am new to GIS area and I need to validate a geometry in WKT format in java, to check whether a simple polygon is a closed loop, i.e the start and end points of the vertices should be the same. I am currently using jGeometry class of oracle spatial(com.oracle.sdoapi), get the first and last vertices and comparing them. also, i am using getType() method to check whether it is a simple polygon or not. The following is the piece of code that am using:
WKT wkt = new WKT();
JGeometry geometry = wkt.toJGeometry(wkt.getBytes());
double[] d1 = geometry.getFirstPoint();
double[] d2 = geometry.getLastPoint();
if(!jGeometry.getType() == jGeometry.GTYPE_POLYGON){
//error message for other geometries
}
Is there any simple way of doing this or is there any API available? I dont want to reinvent the wheel, if it is already done and simple to use. Thanks!
The Java Topology Suite contains a WKTReader class that will suit your purposes. See http://tsusiatsoftware.net/jts/javadoc/com/vividsolutions/jts/io/WKTReader.html. You can use WKTReader to parse the WKT, and look for ParseExceptions, which indicate an invalid WKT.
If the WKT parses, you can then use the instanceof operator or WKTReader.getGeometryType() to determine the type of parsed Geometry class, and see if it's one of the Geometry types (Polygon or Multipolygon) with closed shells like Polygon or Multipolygon.
I need some help with a formula or bit of code for finding the distance to the closest point in a line segment. Effectively, the "distance from the line segment" is going to be used as a sort of "bonding box", so that a user can click relatively close to a line, and it count as clicking on that line.
If you're using Swing, then you should be able to use Line2D.ptSegDist(Point2D) or its various overloads to do all the math for you.
This page explains how to find the closest point on a line.
It also includes a sample implementation in Java.
Java function
public static
double
distanceToSegment( final R3 v, final R3 a, final R3 b )
full gist:
https://gist.github.com/anonymous/6ca967360b5a6613604c416fe50d2d87
from open source library
https://sourceforge.net/projects/geokarambola/
I've just tried to write "line" code to visualize a simple math;
Here it is
Ploygon polygon=new Ploygon();
int x,y;
ploygon.addPoint(0,0);
polygon.addPoint(width,height);
g.drawPolygon(polygon);
The code gives y=x effect;
OK... it is quite simple code; But the thing I am interested to get is points each N pixels during the statement period as {x0,y0}{0,0} and {x1,y1} {width,height} and that is the problem :(
The polygon xpoints array is not handy because it may contain just the same points which were added when addPoint(x,y) method was invoked; so in my case there just two added points which are connected by Polygon but what about all the rest points which stay between these points {x0,y0}{0,0} and {x1,y1} {width,height} ? How to get them?
For example. Coming back to the previous snippet how to find out what point x,y value is when (height%N)=0 etc?
Is there the most optimal way?
Thanks
What you have to realise here is that you are no longer working with pixels/coordinates per se, but you are working with vectors. You'd get much the same image from a polygon contained the coordinates (-500,-500) and (500,500) which is drawn onto a Graphics object which represents the (clipped) area from (0,0) in the bottom left to (100,100) in the bottom right. (ignoring for now that the actual coordinate system of Graphics has an inverted y-axis).
Therefore you have to solve this in a more back-to-basic's Math way rather than a “read the pixels” way. Unless you just want to determine if a given point is in the shape (for which the Shape interface offers a built-in method), you would be looking at calculating the slope of a line and determining functions which represent your line. For instance continuing from the example you have two points (-500,-500) and (500,500) which gives a slope of 1000/1000 = 1. So you could rewrite that function in terms of your x-coordinates as f(x) = -500 + (x + 500). Then if you want to know if the point (100,200) is on that line all you need to do is calculate f(100) and see that it isn't.
Getting back to your example, finding points which match a predicate (height%N =0), we'd be looking for f(x) == 0 mod N and so 'all' you'd need to do is solve the equation for x.