I want to tessellate country shape from GeoTools to display it in 3D on Earth surface. GeoTools use JTS topology suite inside which looks feature rich.
Does it contain utility to tessellate some shape? I see there is triangulation package, but can't figure out, how to use it for shapes with holes.
Also I with it not just connect existing vertices like here
it should fill shape with multiple vertices inside.
UPDATE
I found, that JTS contains class ConformingDelaunayTriangulationBuilder which allows to make wished tessellations somehow, but it works bad. First of all it allows only constraining, which means additional code is needed to remove triangles from concaved regions. And also it tries to conserve Delaunay nature of tessellation, which leads to creating many additional sections.
Finally it causes ConstraintEnforcementException for complex shapes like countries and unusable.
Also I found "triangle" package, which is written in C and implementing Chew's second algorithm and works well
Now I wonder, was it ported to Java or wrapped into it?
I know this post is relatively old, but I recently faced the same situation and needed some Java Library or similar tool to triangulate some complex Polygons (as I wanted to display them on OpenGL, which can only draw triangles as primitive operations).
After quite some search and testing, the library that worked for me was Poly2Tri from Orbgis. You can get that library from Maven here*.
This library has many features, including Polygons with holes, Steiner points to optimize your triangulation, and other stuff. A basic usage example would be the following (based from the example on the linked repo):
//Create the polygon passing a List of PolygonPoints
Polygon polygon = new Polygon(
Arrays.asList(
new PolygonPoint(0, 0, 0),
new PolygonPoint(10, 0, 1),
new PolygonPoint(10, 10, 2),
new PolygonPoint(0, 10, 3)));
//Here you could add holes as needed, passing them as Polygons
polygon.addHole(someHoleYouCreated);
//Next, proceed to calculate the triangulation of the polygon
Poly2Tri.triangulate(polygon);
//Finally, obtain the resulting triangles
List<DelaunayTriangle> triangles = polygon.getTriangles();
Edit: Don't know if you already tried, but JTS Topology Suite also has a DelaunayTriangulationBuilder class (that is without the Conforming part). It is found at org.locationtech.jts.triangulate.DelaunayTriangulationBuilder, and perhaps it works better than the other one you tried but performed badly.
*Note: careful not to use this one instead, as I did at first and found that it was not the correct dependency (wasn't the -core version)
Here's a quick and dirty way using JTS:
First:
Triangulate your geometry with JTS DelaunayTriangulationBuilder
Prepare a set of sites, sites; copy in vertex sites from the initial triangulation
Loop:
Iterate over triangle geometries of the triangulation, adding triangle centroids** to sites
Re-triangulate using sites(now comprised of the original sites and the new centroid sites)
Finally:
Intersect the triangulation with the original geometry to restore its concave hull and any holes
**For this dirty technique, I've found that using triangle centroids lead to better results than the triangle circumcenters even though the latter tends to be used in more formal refinements (Chew, Ruppert and so on..)).
Code
static Geometry refinedTriangulation(Geometry g, int nRefinements, double tolerance) {
DelaunayTriangulationBuilder builder = new DelaunayTriangulationBuilder();
builder.setSites(g); // set vertex sites
builder.setTolerance(tolerance); // set tolerance for initial triangulation only
Geometry triangulation = builder.getTriangles(geometryFactory); // initial triangulation
HashSet<Coordinate> sites = new HashSet<>();
for (int i = 0; i < triangulation.getCoordinates().length; i++) {
sites.add(triangulation.getCoordinates()[i]);
}
for (int refinement = 0; refinement < nRefinements; refinement++) {
for (int i = 0; i < triangulation.getNumGeometries(); i++) {
Polygon triangle = (Polygon) triangulation.getGeometryN(i);
if (triangle.getArea() > 50) { // skip small triangles
sites.add(new Coordinate(triangle.getCentroid().getX(), triangle.getCentroid().getY()));
}
}
builder = new DelaunayTriangulationBuilder();
builder.setSites(sites);
triangulation = builder.getTriangles(geometryFactory); // re-triangulate using new centroid sites
}
triangulation = triangulation.intersection(g); // restore concave hull and any holes
return triangulation;
}
You can use triangle.getExteriorRing().getLength() > N or triangle.getArea() > N to skip over refining already-small triangles.
Example
Raw shape
JTS triangulation
JTS triangulation w/ intersection
1 Refinement
3 Refinements
Related
I have .kml shape files which contain region polygons, what I want to do is to find out that specific marker or point lies inside a polygon. I want to do this in java. Any library to parse through .KML files ?
The JTS Topology Suite is a good choice to correctly calculate geometric relationships in geospatial context. The KML can easily be parsed using a Java library such as JAK or GIScore in which you can access the coordinates of the features.
Here is snippet of Java code using JTS to test if a geospatial point is inside a polygon.
import org.locationtech.jts.geom.*;
// parse KML using JAK or another library
// ...
GeometryFactory gf = new GeometryFactory();
// create polygon
int numPoints = ...
Coordinate[] points = new Coordinate[numPoints];
// set points
points[0] = new Coordinate(...);
//...
LinearRing jtsRing = gf.createLinearRing(points);
Polygon poly = gf.createPolygon(jtsRing, null);
// now create point to test if contained inside polygon
Coordinate coord = new Coordinate(lon, lat);
Point pt = gf.createPoint(coord);
if (poly.contains(pt)) {
// point is contained within bounds of polygon
// do something here
}
The contains() geometry predicate is defined in the JTS javadoc.
To parse the KML data, here is a library (took me two seconds of googling): https://github.com/micromata/javaapiforkml
To check if a coordinate falls into a shape, either the library offers a method for that (didn't check that) - or, you could just create a Java AWT Polygon from the coordinates of a shape (just treat them as points on a 2D surface). Polygon offers a contains(Point2D) method.
https://docs.oracle.com/javase/7/docs/api/java/awt/Polygon.html
I'm looking for an algorithm that provides a way to generate graphical representations of knots (either 2D or 3D, but the former, with vector graphics is preferable).
I've seen many links to knot theory in general, spanning from punctual references to general information.
Before trying to devise something from scratch by myself, I'd like to know about the existence of some existing software that lets you not only represent them (in memory) but visualize in some of their graphical representations (there are many). It could come in the form of a library, or a simple function, or even a pseudocode algorithm that tries to specify how to properly draw a know on screen.
As the previous link suggests, there is a package in Wolfram Mathematica, named KnotTheory that does that (in an almost complete way). However, it is not portable, nor free software and accessing its modules would be very cumbersome for me (a free implementation in Java, just to name a language, but each language is fine, would be be ideal from the portability and openness perspectives).
I've seen that many softwares are available (but most of them are old and not reachable or usable).
Do you have some good pointers to share?
UPDATE:
Since two votes to close this question have appeared, I am restating it in a more pragmatic and clear way: are there algorithms to draw and generate knots? has something been already implemented
UPDATE 2 (for reopening)
The graphical representation could be a 3D rendered object or a 2D svg graphics (I am abstracting from it since I am looking forward a programming language as Processing (or the same Mathematica itself) that provides you the primitives to draw curves (splines, beziers, etc) on screen (and then export them to raster or vector graphics).
The algorithm shall take one knot parametrization as input (ie, if we are talking about knots described by their crossing properties, their values is what is needed), returning one of the graphical representation above (ie even a sequence of points in a 2d space). That is, any parametrization is fine, my objective is just to get introspection on how to draw knots so to get ONE algorithm that does that in a particular way, leading to a particular representation, would be fine (Mathematica's lib seems to be able to draw it in so many representations).
Something like this?
void setup() {
size(300, 300, P3D);
}
void draw() {
background(36, 10, 28);
int f = frameCount%360;
translate(width/2, height/2);
if (frameCount >= 360 && frameCount <= 1080 )
rotateY(radians(f));
stroke(0);
drawKnot(40);
translate(knotX(f)*40, knotY(f)*40, knotZ(f)*40);
noStroke();
fill(180,50,145);
sphere(10);
}
void drawKnot(float sz) {
stroke(200);
for (int i = 0; i < 360; i++) {
point(knotX(i)*sz, knotY(i)*sz, knotZ(i)*sz);
}
}
float knotX(int n) {
return sin(radians(n)) + 2*sin(radians(n*2));
}
float knotY(int n) {
return cos(radians(n)) - 2*cos(radians(n*2));
}
float knotZ(int n) {
return sin(radians(n*3))*-1;
}
Wolfram Mathematica has basic knot theory, including visualization, built in:
http://reference.wolfram.com/language/ref/KnotData.html
This webpage from the software documentation contains many examples of standard knot-theoretic visualization and computation that can be done with Mathematica.
I am trying to display a single magnetic field vector (point in space, with arrow from origin) using data from Android phone sensors. I wrote a simple server in Python to poll the phone for sensor data, and I want to plot the data received in real time. I'm looking for a simple solution, but I can't find any.
I looked at matplotlib, blender, and visual python but I couldn't find a simple enough solution that simply takes the 3 coordinates and plots. The data received is simply a vector with 3 points. The arrow from the origin is not so important, I just want to be able to visualize the moving point in 3d space.
Also, if necessary, I can rewrite the server in Java and use a Java plotting library. I just need some suggestions, and short code examples that achieve this.
You can draw scene by VPython very easily:
from visual import *
import math
def make_grid(unit, n):
nunit = unit * n
f = frame()
for i in xrange(n+1):
if i%5==0:
color = (1,1,1)
else:
color = (0.5, 0.5, 0.5)
curve(pos=[(0,i*unit,0), (nunit, i*unit, 0)],color=color,frame=f)
curve(pos=[(i*unit,0,0), (i*unit, nunit, 0)],color=color,frame=f)
return f
arrow(pos=(0,0,0), axis=(5,0,0), color=(1,0,0), shaftwidth=0.1)
arrow(pos=(0,0,0), axis=(0,5,0), color=(0,1,0), shaftwidth=0.1)
arrow(pos=(0,0,0), axis=(0,0,5), color=(0,0,1), shaftwidth=0.1)
grid_xy = make_grid(0.5, 10)
grid_xz = make_grid(0.5, 10)
grid_xz.rotate(angle=pi/2, axis=(1,0,0), origin=(0,0,0))
grid_yz = make_grid(0.5, 10)
grid_yz.rotate(angle=-pi/2, axis=(0,1,0), origin=(0,0,0))
sphere(radius=0.3)
obj = arrow(pos=(0,0,0), axis=(1,2,3), shaftwidth=0.3)
th = 0
while True:
rate(20)
obj.axis = (3*math.cos(th), 3*math.sin(th), 2)
th += 0.04
VPython is very simple:
pointer = arrow(pos=(0,0,0), axis=(1,2,3), shaftwidth=1)
Just change the axis=(1,2,3) to the 3 points in your vector. More information can be found here.
If c++ is an option you should really take a look at VTK
http://www.vtk.org/
It is very powerful to display 3D vector fields, and is pretty easy to use
So I'm writing a Java app, and I've got an ESRI Shapefile which contains the borders of all the U.S. states. What I need is to be able to determine whether any given lat/lon point is within a specified distance from ANY state border line - i.e., I will not be specifying a particular border line, just need to see whether the point is close to any of them.
The solution does NOT have to be very precise at all; e.g. I don't need to be dealing with measuring perpendicular to the border, or whatever. Just checking to see if going X meters north, south, east or west would result in crossing a border would be more than sufficient. The solution DOES have to be computationally efficient, as I'll be performing a huge number of these calculations.
I'm planning to use the GeoTools library (though if there's a simpler option, I'm all for it) with the Shapefile plugin. What I don't really understand is: Once I've got the shapefile loaded into memory, how do I check to see whether I'm near a border?
Thanks!
-Dan
Assuming JTS for Geometry which is what is included in GeoTools:
public boolean pointIsClose( File file, Point targetPoint,double distance) {
boolean ret = false;
Map connect = new HashMap();
connect.put("url", file.toURL());
DataStore dataStore = DataStoreFinder.getDataStore(connect);
FeatureSource featureSource = dataStore.getFeatureSource(typeName);
FeatureCollection collection = featureSource.getFeatures();
FeatureIterator iterator = collection.features();
try {
while (iterator.hasNext()) {
Feature feature = iterator.next();
Geometry sourceGeometry = feature.getDefaultGeometry();
ret= sourceGeometry.isWithinDistance(targetPoint, distance );
}
} finally {
iterator.close();
}
return ret;
}
The double number will have to come from the CRS which will define the units in which the calculation will be performed.
These are the geotools imports:
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
If you just want to know if point A is within X meters of a state border and X is constant and you don't care which border it is, you can precompute the negative space as a series of boxes. Then all you have to do is a contains check for each of those boxes against the point. If none of them match, you're not in the negative space.
If you can somehow extract the shape for each state from the shapefile, create an envelope that is x meters on a side (with your point in the exact center) and see if those two shapes intersect, you'll be able to answer the question.
If I was using ESRI's ArcGIS Engine, I'd use an ISpatialFilter with the point defined in the geometry (possibly with a buffer) and query that against the States shapefile. Any result(s) returned would indicate that the point was near a state. I'm unfamiliar with GeoTools and, while browsing through their documentation, I didn't come across anything that looked like that type of functionality, but they must have it. You may want to look for examples of how to use GeoTools to perform spatial queries on shapefiles.
I trying to complete a RPG game for a project, but have no idea on how to make the game map.
It doesn't need to be graphical, but the code for the whole map and each tile must be correct.
So far, I thought about making a non-matricial map (as request by the professor) by using an ArrayList which contain all the linked tiles.
public abstract class Casella {
/**
* #uml.property name="tabellone"
* #uml.associationEnd multiplicity="(1 1)" inverse="casella:Tabellone"
* #uml.association name="contains"
*/
private int id;
private boolean free = true;
private List adjacent;
private List items;
private Tabellone tabellone = null;
public void in(){
free = false;
}
public void out(){
free = true;
}
}
This was the code for a single tile (which has 3 classes that extends it). I still have no idea on how to put together and generate a map.
Thank you for your time.
Don't start with the implementation, start with how you would like to use the map. That will give you some constraints how to implement it. For example:
When drawing the map, how do you access it? By coordinate? Or by "go west from tile X"?
[EDIT] I suggest to start with the main loop of the RPG game. You'll need to place the character/token somewhere (i.e. it needs some kind of relation to a tile).
Then you need to move the character. A character must be able to examine the current tile (opponents, items, type). It needs a way to know how it can move (i.e. is there a wall to the right?)
This gives you an interface for your map: Services which it renders for other objects in the game. When you have an idea of what the interface needs to provide, that should give you an idea how to implement the map (the data structure).
As for generating a map, use a random number generator plus some "common sense". Have a look at the adjacent tiles: When they are all city, this tile is probably city, too. Same for plains. Hills are singular items, and they are least frequent.
Run this code, print the map as ASCII ("C"ity, "P"lain, "H"ill) to see if it works.
To generate a map like this without using a matrix, I recommend starting with a center tile and then populating the map outwards by using a modified breadth first search algorithm. First of all, we'll need something a little better than a list of adjacent tiles. You could simply have four variables, one for each direction that stores the next tile, as such:
private Tabellone up = null;
private Tabellone down = null;
private Tabellone left = null;
private Tabellone right = null;
Say we start with the center-most tile. All you have to do now is figure out how many of the directions are null, and create a new Tablellone object for each direction, making sure to set each of the variables in this current object and to set the appropriate opposite variable in the object created.
Tabellone adj = new Tabellone();
up = adj;
adj.setDown(this);
Once you've filled out all of the directions on this tile, you then choose one of the other tiles you've created and perform the same operation. This is where the breadth-first search algorithm comes in. You can use a queue to go through each tile you've created and fill out the directions. To make the algorithm stop, simply set a limit on the number of tiles you want to create and use a counter to keep track of how many have been created.
int count = 0;
ArrayList<Tabellone> queue = new ArrayList<Tabellone>()
queue.add(/*center tile*/);
while (count < 100) { //if we want 100 tiles
//take out the center tile from the beginning of the array list, create a tile for each direction and add those tiles to the array list, then increment count by 1.
}
Note: This algorithm as it stands will create a diamond shaped map, if you want a square, you'd need to have a variable for each diagonal direction as well.
Of course, if this seems a little more complicated than you'd like, I'd recommend a coordinate system.
The walls, baggs and areas are special containers, which will hold all the walls, baggs and areas of the game.
private String level =
" ######\n"
+ " ## #\n"
+ " ##$ #\n"
+ " #### $##\n"
+ " ## $ $ #\n"
+ "#### # ## # ######\n"
+ "## # ## ##### ..#\n"
+ "## $ $ ..#\n"
+ "###### ### #### ..#\n"
+ " ## #########\n"
+ " ########\n";
This is the level of the game. Except for the space, there are five characters. The hash (#) stands for a wall. The dollar ($) represents the box to move. The dot (.) character represents the place where we must move the box. The at character (#) is the sokoban. And finally the new line character (\n) starts a new row of the world.
Is speed or memory a huge concern for this project? If not, why don't you use a 2d array?
Something like
Casella map [][] = new Casella[xSize][ySize];
From here it is easy to conceptualize, just picture it as an excel spreadsheet where each cell is a tile on the map.
The way you are going is fine though, just a little hard to conceptualize sometimes. You have a List of adjacent tiles. So, when creating your map you start somewhere, possibly top left, and go from there.
You could use nested for loops in order to set up the map, and to help determine the edge items.
for(int i = 0; i < XSIZE ; ++i)
for(int j = 0; j < YSIZE ; ++j)
if(j==0) //found left edge (i.e. no adjacent ones to the left)
if(j==(YSIZE)) //found right edge (you get the picture)
The point of using the loops, and checking the edges, is that you are going to need to link backwards and forward, up and down for each tile except at the edges, where you will have either 2 or 3 links instead of 4.
The code needs to be correct really isn't a functional requirement, so its hard to say exactly what is correct without knowing more about your game/map.
Assuming you have a map that has X tiles and no ordered adjacency a non-matricial solution is best, a common solution is to just model it like a graph using either adjacency list for non-symmetric adjacency or incidence list for symmetric adjacency. If youre using an incidence list you need an edge object that contain the vertices the edge is connecting, if youre using adjacency list a multimap might be cool to use.
If you want a non-matricial solution with ordered adjacency AlbertoPL has the solution for that.
Assuming you have a map thats X tiles wide and Y tiles tall and the tiles that are next to each other are adjacent, so that each tile has at max 4 and min 2 adjacent tiles you could use a matrix to access the tiles and also represent adjacency by matricial adjacency. The idea is that map[Y][X] is adjacent to map[Y+1][X] and map[Y][X+1] and reversely.
This solution could also fit max 6 and min 3 tile adjacency if tile [Y+1][X+1] is adjacent to tile [Y][X].
Upside to this is that you can easily parse the map, and since it has 2 dimensions its natural to model it like this.
Downside is that once a tile is set, you cant change its adjacency without changing the matrix. As this isnt what you professor suggested you might not want to do it, but if you have (static) ordered adjacency this might be easiest way to do it.
I managed this by using adjacency lists.
Each cell will have an ArrayList containing the indexes of the adjacent cells. Those indexes are the ones that the said cell have in the map ArrayList of cells.
http://en.wikipedia.org/wiki/Adjacency_list
If it's a tile-based map, then each room has a fixed relationship with its adjacent rooms. You may not need to worry about co-ordinates (although it might be simpler if the tiles are square), but you will need to worry about directions.
If the tiles are square, cardinal directions (n, s, e, w) may be all you need care about. If they're hex tiles, you can number your exits 1-6 (perhaps with static final constants). Then each adjacent tile may be linked to this one along with its exit.
As said by Aaron, you need to decide first how the maping coordinates will be.
But you are not constrained by an X-Y-Z coordinate system. For instance, each tile could be linked to any other tile on your map. It all depends on how you want to build it.
You say that you're building an RPG game, then you need to have a good view of the terrain surround your character. Is it multi-level? How does the character move from one tile to another? Is the movement one way?
There are, literally, dozens of question to be asked when designing a map for a game.
You need to plan it very well first, before starting coding.