I am trying to create a 3D wireframe by interpolating known points on generated cross-sections. I need a smooth polynomial interpolating function for the collection of points with known XYZ coordinates that need to be interpolated. I will then need to evaluate this function to obtain the rest of the XYZ-coordinates in between. I have used cubic spline interpolation in the past for 2D applications but I haven't found anything useful for 3D applications.
I have looked into Tricubic interpolation but my points are not strictly increasing in the y and z coordinates and I don't have any known function that describes them. Finally I have looked into a reliable Catmull-Rom spline library.
Is there any interpolation method or library that can help me create smooth 3D curves given these x[], y[],z[] arrays. PS. My solution ideally needs to in java.
Related
I am working on my university project, and I use GeoTools library. My task is to implement AGNES (agglomerative nesting) algorithm that considers spatial data. To do this I need to calculate distances between spatial objects e.g. points, curves, polygons.
LineString which can be converted to Curve is a GeoTools class that inherits Geometry methods including distance(). My question is how is the distance between two LineString objects calculated? Is it the shortest line segment connecting both curves? Also, I am curious how similar is done with polygons.
An algorithm with an explanation can be found in the answer of this question find-shortest-path-from-one-geometry-to-other-on-shapely. The distance is not necessarily achieved in two vertex.
The algorithm basically computes the distance between each pair of edges, including the case where the distance is achieved in the interior of the edge (by projecting vertex points of one edge to the other edge).
The code is in python, but the geometric library it uses is shapely, that is based on GEOS library, which in turn is a ported version of JTS.
So I have some irregularly spaced data that I want to interpolate onto a regular grid. (I want to do exactly this but in Java) Here's a picture:
Basically I have the x and y coordinates of each point and a z value associated with each point and I want to interpolate between them and fill in the center of my image.
What is the best way to do this using Java? Is there a built in 2D interpolation library I can use or should I try a "roll my own" approach?
This post and this one also seem to be trying to do about what I am but their answers don't quite apply.
Someone else with the same problem but no solution.
Note: I am using JavaFX-2 so if I could somehow use their Interpolator class that'd be great.
.
.
EDIT:
If anyone stumbles upon this and wants to know what I ended up using, it was a Delaunay Triangulation implementation from BGU:
Main Site
Code API
If linear interpolation is sufficient, I suggest you to use a 3d mesh with Gouraud Shading for drawing:
Convert the 2d point cloud to a mesh (you can google for existing algorithms)
Mapping the z value of each point to the vertex' color
Using Gouraud Shading to enable linear interpolation between the vertex colors
Creating a camera on top to the mesh and using a othonormal projection (to avoid perspective)
You say that you can use JavaFX. JavaFX supports 3d scenes and you can build your own meshes. But looking into the JavaDoc of TriangleMesh, I can't find any method to set the vertex color I found only a method to set the (x,y,z) and (u,v) (texture coordinates) coordinates.
I am making an app where I need to draw a sine wave between two given points. I have Google'd, and Google'd, and I haven't found anything that I have found suitable.
Is there an efficient way in android to use some pre defined points to draw a smooth wave like form?
You can use the android.graphics.Path class to construct a set of quadratic or cubic Bézier spline curves between your set of control points.
I have data in the form of a 2D array of intensities that should be plotted in a contour plot. In the end it should look like a topographic map with contour lines like the following image:
The idea is that the typical multitouch gestures (pinch for zooming, dragging for moving around) can be used to navigate the contour plot. The maximum size of the data should be around 4k*4k points, each 4 bytes big.
Is there some plotting library that I can use, or do I have to start from scratch? Is there an easily implemented algorithm for that?
I don't know of any plotting libraries for Android (or Java for that matter), but I do know a thing or two about plotting in general:
An easy algorithm for creating contours would be Marching Squares. Marching squares creates polygons from your array of data. There should be plenty of examples of this algorithm in Java (try Google Code Search, but read licenses before you use).
If you want to zoom in far you probably want to create bezier curves from these polygons to smooth them out, an example algorithm (with code that should be easily ported to Java) can be found here.
Note: If you want to fill the contours with a color you should consider using a fragment shader instead of creating polygons. Send the data to the shader as a texture and use the intensity to assign a color to each pixel. For this you should know some OpenGL.
As #Markus Johnsson said, one way to visualize your two-dimensional array of data is to use the Marching Squares algorithm. But in your case, it seems you need its implementation based on isolines instead of isobands (which use polygons Markus mentioned about).
Implementation based on isolines is easier to write it from scratch. It is mainly due to the fact, that you have to check only whether a given value is under, or above specific isovalue (vs below-within-above specific range in isoband implementation). This results only in 16 possible configurations of lines drawn in a single isocell (vs 80 polygon configurations in isobands implementation).
It is often desirable to interpolate your data before using it in the creation of the contour map. One way to do so, is to use Bicubic Interpolation.
I've written recently a simple implementation of the filled two-dimensional contour plot based on the Marching Squares algorithm and its isoband variant. This implementation also use mentioned Bicubic Interpolation for smoothening the data. You can find this simple package here. It is written under GNU GPLv3 license (or later). In order to use it in your project you have to copy and paste org.contour2dplot.* to the project's location.
All you need to do in order to draw a contour map with the use of the aforementioned package is to prepare a double[][] data and create a Contour2DMap object. Example use can look like this:
// Specify in the constructor width and height of the contour map.
Contour2DMap contour2DMap = new Contour2DMap(600, 600);
// Specify size for the contour map container.
contour2DMap.setPrefSize(600, 600);
// Set data.
contour2DMap.setData(data);
// Set iso factor, which is a step between subsequent iso values.
contour2DMap.setIsoFactor(1.0);
// Set interpolation factor.
contour2DMap.setInterpolationFactor(10);
// Set contour map color scale - "Color" or "Monochromatic".
contour2DMap.setMapColorScale("Color");
// Draw all elements on the contour map.
contour2DMap.draw();
Contour2DMap object inherits from javafx.scene.layout.Pane, so you can nest it in other javafx.scene.layout.* objects, such as BorderPane.
In order to make contour map interactive you may consider overwriting the javafx.scene.chart.Chart object and nesting Contour2DMap in it.
You may also consider rewriting org.contour2dplot.* for the isolines variant of the Marching Squares algorithm.
Below are two screenshots of Contour2DMap for setMapColorScale("Color") and setMapColorScale("Monochromatic") respectively.
I have two geo-spatial simple convex polygon areas, in latitudes and longitudes (decimal degrees) that I want to compute using Javas Polygon class. I basically want to see if these two lat,long polygons intersect, and to calculate the areas (in sq meters) of both.
Now java.awt.Polygon class only uses x,y co-ordinate system, but I need to use lats,longs.
How can I do this, and/or is there any other classes/libraries available?
Why not use Polygon class multiplying coordinates for 10^n making them integers? Polygon accepts arrays of int as points.
Just an Idea
All you need to do is convert from spherical to rectangular coordinates if you think that really matters.
I'm not sure that it does, because the java.awt.Polygon is merely a data structure holding for pairs of values. If you read the javadocs, they say
The Polygon class encapsulates a description of a closed, two-dimensional region within a coordinate space. This region is bounded by an arbitrary number of line segments, each of which is one side of the polygon. Internally, a polygon comprises of a list of (x,y) coordinate pairs, where each pair defines a vertex of the polygon, and two successive pairs are the endpoints of a line that is a side of the polygon. The first and final pairs of (x,y) points are joined by a line segment that closes the polygon.
They happen to label those points as x and y, which makes all of us think rectangular coordinates, but they need not be from your point of view. A bug on the service of your sphere would view it as a 2D space. Your radius is large and constant. You just can't count on using any of Polygon's methods (e.g., contains(), getBounds2D(), etc.)
In this case, the important thing is your area calculation. You can use a Polygon for your area calculation, storing lats and longs, as long as you view Polygon as a data structure.
You might also thing of abandoning this idea and writing your own. It's not too hard to create your own Point and Polygon for spherical coordinates and doing it all with that coordinate system in mind from the start. Better abstraction, less guessing for clients. Your attempt to reuse java.awt.Polygon is admirable, but not necessary.
You can perform the area calculation easily by converting it to a contour integral and using Gaussian quadrature to integrate along each straight line boundary segment. You can even include the curvature of each segment at each integration point, since you know the formula.
Going off my intuition here.
If the polygons are small in ratio to the size of the planet you can treat them as flat polygons. The steps involved would be converting the lat/long into absolute x/y/z, taking any three of the points and finding the normal of the plane the polygons lie on and then using this to project the points into two dimensions. Once you have the 2D points it's easy to calculate the area or if they intersect.
Probably not the best answer but hopefully it will motivate some people to make better ones because it's a good question.
Maybe you could use GeoTools for this. It allows you to create Geometry objects, and check wether they intersect (see: Geometry Relationships)
Here is a solution that works like a charm:
Class PolygonArea from net.sf.geographiclib
Refer link below with sample code:
https://geographiclib.sourceforge.io/html/java/net/sf/geographiclib/PolygonArea.html
gradle dependency:
compile group: 'net.sf.geographiclib', name: 'GeographicLib-Java', version: '1.42'