Java Topology Suite has Geometry class, which has getNumPoints() method. According to documentation, it counts all vertices in all constituent geometries.
How to enumerate all these points? They can be obtained by getCoordinates() method, but this looks not optimal, since (1) is not iterative and (2) requires to convert each coordinate tuple into Point by GeomertFactory.
As you probably have some proper geometry type like LineString or Polygon, use that (cast your Geometry to it), then you can use getPointN(index).
Coordinates are not Points by the way. Coordinate is not a geometry in JTS, just a class to hold numeric values. Points are actual geometries.
Related
I've done a fair bit of reading around this, and know that discussions regarding this algorithm in Java have been semi-frequent. My issue with implementing Dijkstra's algorithm in Java is simply that I'm not sure how to prepare my data.
I have a set of coordinates within an array, and a set of 1s and 0s in a matrix that represent whether there is a path between the points that the coordinates represent. My question is, how do I present this information so that I can search for the best path with Dijkstra? I have seen many people create a "Node" class, but they never seem to store the coordinates within that Node. Is there some standardized way of creating this kind of structure (I suppose it's a graph?) that I am simply missing?
Any help would be appreciated.
There are two main options:
1. You can use an adjacency matrix in which rows an columns represent your nodes. The value matrix[x, y] must be the weight(e.g. distance/cost etc.) to travel from x to y. You could use the Euclidian distance to calculate these values from your coordinate array;
2. You can implement a couple of classes (Node, Edge - or just Node with a internal Map to another node and the weight as a map value) - it is a graph indeed.
I have a curve (say JTS edge):
How to find all curve direction change points that surpasses given angle using JTS (Java) or NTS (C#):
I did some research and made some tests on JTS, and the best way I found is:
Create polygons and use the function union
Then iterate over the Coordinates, and create a sub-array on each "hard angle" (negative scalar product) and when the sum of angle reaches 180 (don't take the last angle to avoid non-function issues)
Then I change the base to an orthonormal base with x(firstElemOfSubArray, lastElemOfSubArray) by computing the base-changing matrix, and I then recompute the sub-array in a new coordinate system
I then create a function using org.apache.commons.math3.analysis.interpolation.SplineInterpolator to interpolate the function of the course, and then I get the derivative and search the extrema (don't take elements with an ordinate that is too low). With its absysse you can find which point is an inflexion point
So the point you search for are first elements of each sub array, and its inflections points (if there are any)
I'm making a simple Vector class with a simple usage, so I don't want to import a whole library (like JScience...) for something that I can do myself.
Currently I have made this code so far:
public void add(Vector2D v){
double ang = this.angle*Math.PI/180;
double mag = this.magnitude;
double ang0 = v.angle*Math.PI/180;
double mag0 = v.magnitude;
//vector to coordinates
double x1 = mag*Math.cos(ang);
double y1 =-mag*Math.sin(ang);
//adding the other vector's coordinates
double x2 =x1+mag*Math.cos(ang0);
double y2 =y1-mag*Math.sin(ang0);
//back to vector form
double newMagnitude = Math.sqrt(x2*x2+y2*y2);
double newAngle = Math.atan2(y2,x2);
this.magnitude = newMagnitude;
this.angle = newAngle;
}
It's converting both vectors to coordinates and then back with the trigonometric functions, But those are extremely slow, and the method will be used very frequently.
Is there any better way?
First off, some terminology 101:
Point: a dimensionless entity that a space is made of.
Space: a set of points.
Euclidean space: a set of points, together with a set of lines and with the notion of closeness (topology). The set of lines is bound by the Euclid's axioms. It is uniquely defined by its dimension.
Vector: a translation-invariant relationship between two points in an Euclidean space.
Coordinate system: a mapping from tuples of real numbers to points or vectors in some space.
Cartesian coordinate system: A specific mapping, with the properties (in case of the Euclidean 2D space) that the set of points ax+by+c=0 is a line unless a,b are both zero, that the vectors [0,1] and [1,0] are perpendicular and unit length, and that points in space are close together iff they are close together in all coordinates. This is what you refer to as "coordinates".
Polar coordinate system: Another specific mapping, that can be defined from the cartesian coordinates: [arg,mag] in polar coordinates map to [cos(arg)*mag, sin(arg)*mag] in cartesian coordinates. This is what you refer to as "vector form".
The cartesian coordinate system has multiple benefits over the polar coordinate system. One of them is easier addition: [x1,y1]+[x2,y2]=[x1+x2,y1+y2] and scalar multiplication: [x1,y1].[x2,y2]=x1*x2+y1*y2. Additive inversion is slightly easier as well: -[x,y]=[-x,-y]
Another benefit is that while polar coordinates are strictly 2D (there is no unique extension - the spherical coordinate system is a candidate, though), cartesian coordinates extend naturally to any number of dimensions.
For this reason, it is beneficial - and usual - to always store vectors in their cartesian coordinate form.
If you ever need vectors in their polar form, then (and only then) convert, once and for all.
Polar coordinates not as useful. They can be used for input and output, but they are rarely useful for computation.
You keep storing your vectors in the polar form. You convert them to their cartesian form for computation, then convert back to polar - only to convert them to the cartesian again.
You should store your vectors in the cartesian form. The performance improvement should be clearly visible if you drop the redundant conversion.
Even if you want to rotate a vector, it's not beneficial to convert to polar and back. Rotation by a signed angle a is as easy as [x*cos(a)+y*sin(a), y*cos(a)-x*sin(a)]. That's two trigonometric functions (at most - you can cache these values) to rotate an entire array of vectors.
This is a fairly remedial question. I have been looking at the documentation for the JTS DelaunayTriangulationBuilder and I am at a loss as to how to do what seems like it should be a simple thing. I wish to take a series of points, triangulate them, and then interpolate the Z value of a random point within that mesh. It's non-obvious from a cursory reading how to do this. Any ideas?
After you've loaded up the triangulation object, call getSubdivision() on it to get the triangulation. It uses a quad-edge data structure, which you'll need later. (It's easier to understand if you know what a half-edge or winged-edge representation is.) The resulting QuadEdgeSubdivision has a method locate that, given a coordinate, returns one of the edges of the enclosing triangle (as a quad-edge). Get its origin vertex with orig() and its destination vertex with dest(). Get another edge with oNext() Its destination vertex is the third vertex (also dPrev().origin() is the same vertex). Now that you have the three vertices, represent your test point as a Vertex and call interpolateZValue.
For example:
public static double
interpolateZ(DelaunayTriangulationBuilder triangulation,
Coordinate coordinate) {
QuadEdgeSubdivision quadEdgeSubdivision = triangulation.getSubdivision();
QuadEdge edge = quadEdgeSubdivision.locate(coordinate);
return new Vertex(coordinate.x, coordinate.y)
.interpolateZValue(edge.orig(), edge.dest(), edge.oNext().dest());
}
You're right, though. It's not obvious how to do this from reading their API.
I'm not familiar with JTS DelauneyTriangulationBuilder, but it sounds like you have a collection of points (x,y,z), and you are submitting the 2D (x,y) pairs to the triangulator. This gives you a planar triangulation of the (x,y) points, but also a mesh who's vertices are the original (x,y,z) points.
Once you have a triangulation, you wish to find the point (p,q,r) on the mesh that corresponds to the planar point (p,q). To do so, find the triangle T of the Delauney triangulation that contains (p,q). Find the barycentric coordinates of (p,q) relative to T, and use these to compute a weighted average r of the z values corresponding to the vertices of T. That weighted average is the Z value you're looking for. In other words, (p,q,r) is on the mesh.
I need to calculate the distance from a point [x y z] to the surface of an object (at this stage a simple rectoid, but later an arbitrary shape) along [0 0 1].
I could do this defining the surfaces as planes using unit vectors and then doing a linear algebra calculation to find the distance to all the planes along [0 0 1] but as someone fairly new to coding and Java, I wanted to see if there was a library or a more efficient way of doing this as in the long term I may have complex convex objects, so need to be careful to use standard practices (so I can use something else to generate the planes!)
Thanks,
If you are using Point3D to represent your points then you have a distance method you can use to calculate the distance. So the question is which point on the surface do you want? If you just need any point on the surface you could just pick one of the corner points and use that to calculate the distance.