Is there and equivalent of Point class but for 3D points? - java

I would like to store the x y and z co-ords for some objects for a game but I can't find a built in class like Point. Is there a nice standard class I could add in and use that would handle distance between points/bearings from one object to another etc?

Having recently done some vector mapping (including z / 3D), and seeing your Android tag, I recommend rolling your own.
The reasons are many:
You can customize to meet your specific precision / memory / performance constraints.
If multi threaded, you can make your class immutable and thread-safe
I.e. If memory constrained you can store all three dimensions in an int or long
If cpu constrained you can use plain-old separate numbers
If GC / Garbage constrained, you can recycle and pool instances (mutable)
In the end, most of these primitives are quite simple to write, test, etc. The main methods you'll need to write (beyond boilerplate constructor/get/set/...)
- Distance
- Dot product
- Unitize (make length == 1 for various math ops)
- And I've used DistanceSquared in the past for comparison functions... This removes the sqrt operator from most distance methods, while computing a relative distance useful enough for comparing point distances etc.

Maybe Point3D is what you need.

There is also a JavaFX class Point3D that meets your requirements.

Related

Calculating the principal axis/eigenvalues and -vectors of large dataset in Java

I have a large dataset (>500.000 elements) that contains the stress values (σ_xx, σ_yy, σ_zz, τ_xy, τ_yz, τ_xz) of FEM-Elements. These stress values are given in the global xyz-coordinate space of the model. I want to calculate the main axis stress values and directions from those. If you're not that familiar with the physics behind it, this means taking the symmetric matrix
| σ_xx τ_xy τ_xz |
| τ_xy σ_yy τ_yz |
| τ_xz τ_yz σ_zz |
and calculating its eigenvalues and eigenvectors. Calculating each set of eigenvalues and -vectors on its own is too slow. I'm looking for a library, an algorithm or something in Java that would allow me to do this as array calculations. As an example, in python/numpy I could just take all my 3x3-matrices, stack them along a third dimension to get a nx3x3-array, and pass that to np.linalg.eig(arr), and it automatically gives me an nx3-array for the three eigenvalues and an nx3x3-array for the three eigenvectors.
Things I tried:
nd4j has an Eigen-module for calculating eigenvalues and -vectors, but only supports a single square array at a time.
Calculate the characteristic polynomial and use cardanos formula to get the roots/eigenvalues - possible to do for the whole array at once, but I'm stuck now on how to get the corresponding eigenvectors. Is there maybe a general simple algorithm to get from those to the eigenvectors?
Looking for an analytical form of the eigenvalues and -vectors that can be calculated directly: It does exist, but just no.
You'll need to write a little code.
I'd create or use a Matrix class as a dependency and find methods to give you eigenvalues and eigenvectors. The ones you found in nd4j sound like great candidates. You might also consider the Linear Algebra For Java (LA4J) dependency.
Load the dataset into a List<Matrix>.
Use functional Java methods to apply a map to give you a List of eigenvalues as a vector per stress matrix and a List of eigenvectors as a matrix per stress matrix.
You can optimize this calculation to the greatest extent possible by applying the map function to a stream. Java will parallelize the calculation under the covers to leverage available cores to the greatest extent possible.
Follow-up: This is the way that worked best for me, as I can do all operations without iterating over every element. As stated above, I'm using Nd4j, which seems to be limited in its possibilities compared to numpy (or maybe I just didn't read the documentation thoroughly enough). The following method uses only basic array operations:
From the given stress values, calculate the eigenvalues using Cardano's formula. Only element wise instructions are needed to do that (add, sub, mul, div, pow). The result should be three vectors of size n, each containing one eigenvalue for all elements.
Use the formula given here to calculate the matrix S for each eigenvalue. Like step 1, this can obviously also be done using only element-wise operations with the stress value- and eigenvalue-vectors, in order to avoid specifiying some complicated instructions on which array to multiply according to which axis while keeping whatever other axis.
Take one column from S and normalize it to get a normalized eigenvector for the given eigenvalue.
Note that this method only works if you have a real symmetric matrix. You also should make sure to properly deal with cases where the same eigenvalue appears multiple times.

DESIGN PROBLEM: How to use composition the best

I'm working on a project and have some doubts about it's design.
How can I design the following problem the best (in JAVA):
Class A with the following attributes:
HashSet of Pixels where each pixel has x,y coordinates and value v between 0-1.
instance of class B.
Class B with the following function:
a function that gets a Pixel and returns its left neighbor.
When I'm in class A I want to use B.function on each pixel in A and add it to the HashSet only if it's not already there. The problem is that I don't want to send the HashSet to the function, how bad is it to return new instance of Pixel from the function if it might already exist (This function going to run on many pixels and will create many unused instances of Pixel).
What other options do I have?
Since you use Set<Pixel> you have to create new Pixel instance to check if it exists in set or not.
If set contains N elements after calling B.function method you will create extra N Pixel nodes. If all elements are new, you just add them to set, in other case Garbage Collection needs to sweep them. One of drawbacks is we need to create m (wheren m <= N - number of Pixel-s which already exists in set) and later we need to collect them by GC. How big is m/N ratio depends from your algorithm and what you are actually doing.
Lets calculate how many memory we need to consume for N = 1_000_000 pixels in set. We know that int is a 4 bytes and double is 8 bytes, lets add extra 8 bytes for an object and 8 bytes for a reference. It gives 32 bytes for every instance of Pixel object. We need to create N objects which gives 32MB. Let's assume that our ratio is 50% so, 16MB we allocated just to check it is not needed.
If this is a cost you can not pay you need to develop algorithm which allows you iterate over Set<Pixel> in an order from left-to-right. So, left neighbour of Pixel X is before X.
Assume that left neighbour of Pixel X(x, y) is pixel X'(x - 1, y). Pixel B(0, y) does not have left neighbour. You need to use TreeSet and implement Comparable<Pixel> interface in Pixel class. Simple implementation could look like this:
#Override
public int compareTo(Pixel o) {
return this.y == o.y ? this.x - o.x : this.y - o.y;
}
This allows you to iterate set in order from left to right: (0, 0), (1, 0), ...., (x - 1, y), (x, y), (x + 1, y), ... , (maxX, maxY). So, when you iterate it you can check whether previous element is a left neighbour of current Pixel. Example implementation could look like below:
void addNeighboursIfNeeded() {
Set<Pixel> neighbours = new HashSet<>(pixels.size());
Pixel last = null;
for (Pixel p : pixels) {
if (p.getX() == 0 || p.isLeftNeighbour(last)) {
// a left border pixel
// or last checked element is a left neighbour of current pixel.
last = p;
continue;
}
// last element was not our left-neighbour so we need to call b method
Pixel left = b.getLeft(p);
neighbours.add(left);
last = p;
}
// add all new neigbours
pixels.addAll(neighbours);
}
This should allow you to save this memory which is allocated for duplicated Pixel objects.
I can see here few concerns regarding object oriented programming.
Encapsulation violation: When you call function of B from A which operates on A's data (which you are avoiding by not sending HashMap), it violates encapsulation (If there is a reason, its acceptable though). Is it possible to move that function (operating on A's HashSet) to A? This will protect A's state from getting exposed.
Proliferation of classes: There is a possibility that there will be large number of objects of Point type. You can think of using Flyweight GOF design pattern, it will externalize the state of each point and will make it reusable. and will reduce number substantially.
Passing large collection of Points to method in B: If you can shift method from B to A, this point gets resolved. Anyway java will pass this collection by reference. But in that case its open for modifications from external classes (need to take care of this aspect).
Abstraction of type Point: If class Point has only state and no behavior, it will lead to violation of encapsulation. Can you shift the method getNeighbour() in to Point? as it will make Point immutable (which is essential). Off course actual algorithm can be delegated to another class (if its independently varying responsibility and has hierarchy of algorithms, think of GOF Strategy pattern here).
Uniqueness of points in collection: which your set will take care with due care about appropriate Hash and logical equality for class Point.

Can Java Comparable<Object> fail on a max/min cross-comparison?

I've working on a depth sorting problem, here's an example case I constructed
There are two planes, one hovering above the other, and they are sectioned into rectangluar polygons. Each polygon is defined by it's 'real-world' coordinates, as well as defined with a camera and view projections to produce a perspective view, as shown. A trace-printout of an example polygon produces
Zn = -0.225, Zf = -0.432
v0 (13, 33, 32.7) (-0.358, -0.065, -0.295, 180.737)
v1 (29, 33, 32.7) (-0.192, -0.142, -0.225, 173.247)
v2 (29, 33, 7.2) ( 0.011, 0.023, -0.375, 190.239)
v3 (13, 33, 7.2) (-0.148, 0.087, -0.432, 197.730)
This sample is one belonging to the green plane y=33, the non-projected vertices are v0 to v4 = (13,33,32.7),(29,33,32,7),(29, 33,7.2) and (13,33,7.2)
The projected coordinates, using a standard camera and view model, are shown following. If p(i) is the projected coordinate then -1 < p(i).x,p(i).z,p(i).z < 1. The fourth value is the homogenous W coordinate when prepared for rendereding divided into each p(i)(x,y,z), it is preserved as a reference value because it gives the distance from the 'camera' to a perpendicular plane of a given vertex.
The third column in the second series of brackets are the projected Z-values, and importantly for this problem The values Zn=depth of nearest vertex, and Zf=depth of farthest vertex
The question
This question is motivated by all of the above but is also independent of any knowledge of graphics rendering. My motivation is to depth-sort the quadrilateral polygons primarily on their Z-values
According to Painter's algorithm the first check on rendering order between two polygons is if the Z-near and Z-far are separate and should imply unambiguous spacial separation.
A simplified extract of the comparison
class Extent implements Comparable<Extent> {
double Zn;
double Zf;
#Override
public int compareTo(Extent ext2) {
if (Zn < ext2.Zf) return 1;
if (ext2.Zn < Zf) return -1;
return 0;
}
}
My Problem
When I run the comparison against a large set of polygons, sometimes I get a
java.lang.IllegalArgumentException: Comparison method violates its general contract exception. While often the rendering looks good as above, sometimes it fails. But why, I haven't been able to find a fail-case, and shouldn't comparing on two max,min in this way always be transient?
Does anyone know of an example set that would fail, subjected to this comparison? And, perhaps, are you able to spot a logical error in my method? (while insight in the internals of the compare method is the primary enquiry, if you are familiar with 3d depth-sorting please feel free to comment)
You should use an external Comparator to compare with instead of trying to implement Comparable which for complex objects is almost always the wrong way to do it.
Comparable works great for objects with a single or very few attributes that need to be the same in all cases. Like a complex object with an ID that is unique which is the only thing that is compared.
It does not work for complex cases where all the attributes are not considered in all cases. For those times you use a Comparator or better yet Ordering from the Guava library so that you can do elegant chaining and compositions.
Also sorting on triangles makes this exercise trivial because they can never be non-planar and have one less point to compare.
Your algorithm won't satisfy the compareTo contract, because of transitivity failure; you're not defining a total ordering. Consider three Extents
p1(0,3) p2(0,1) p3(2,3)
The implementor must ensure that p1.compareTo(p2) == 0 implies that
sgn(p1.compareTo(p3)) == sgn(p2.compareTo(p3)) for all other points.
p1.compareTo(p2) is 0.
p1.compareTo(p3) is 0, but p2.compareTo(p3) is -1.
The "best" way to sort ranges will depend on what exactly you want to do with the sorted list, but you'll most likely end up sorting on either the near, far, or center values.

Matrix multiplication java 1.8

Do you think it would be possible to implement sparse matrix operations using the new Stream interface in Java 1.8 ? If yes, how do we need to implement the matrixes and the operations. Clearly, I am looking for it for being able eventually to use the "automatic" parallelization.
It can clearly be done. How about something like below for a simple SPMV (Sparse matrix vector multiplication), with the sparse matrix represented in the coordinate COO format (the simplest sparse format out there):
class COO {
int x, y, value;
}
public static ArrayList<Integer> spmv(List<COO> values, ArrayList<Integer> v) {
final ArrayList<Integer> result = new ArrayList<>(Collections.nCopies(v.size(), 0));
values.stream().forEach(
coo -> result.set(coo.x, result.get(coo.x) + coo.value * v.get(coo.y))
);
return result;
}
But I sincerely suggest you use something pre-coded, if you don't want to spend the next 3 years of your life understanding the performance implications of sparse matrix operations.
This is quite a large research/optimisation topic and there are many factors to consider like (just off the top of my head):
scheduling / reordering of matrix values to improve cache performance
using an optimal storage format for specific problems (e.g. see this survey on netlib)
There are many implementations out there that can achieve orders of magnitude improvements in performance versus hand crafted implementation. To name a few, check out:
Intel MKL Sparse BLAS
Nvidia's cuBLAS
I would just write bindings to those if they don't exist already, although something like la4j looks quite promising.

2D-Array : prefered way access items

So here I am tonight with this question that came up into my mind :
What is your favourite way to access the items of a m x n matrix
there is the normal way where you use an index for the columns
and another index for the rows matrix[i][j]
and there's another way where your matrix is a vector of length m*n
and you access the items using [i*n+j] as index number
tell me what method you prefeer most , are there any other methods
that would work for specific cases ?
Let's say we have this piece of C(++) code:
int x = 3;
int y = 4;
arr2d[x][y] = 0xFF;
arr1d[x*10+y] = 0xFF;
Where:
unsigned char arr2d[10][10];
unsigned char arr1d[10*10];
And now let's look at the compiled version of it (assembly; using debugger):
As you can see there's absolutely no penalty or slowdown when accessing array elements no matter if you're using 2D arrays or not, since both of the methods are actually the same.
There are only two reasons to go for the one-dimensional array to represent n-dimensions I can think of:
Performance: The usual way to allocate n-dimensional arrays means that we get n dimensions that may not necessarily be allocated in one piece - which isn't that great for spatial locality (and may also result in at least some additional memory accesses - in the worst case we need 1 additional read for each access). Now in C/C++ you can get around this (allocate memory in one piece, then afterwards specify the correct pointers; just be really careful not to forget this when you delete it) and other languages (C#) already can do this out of the box. Also note that in a language with a stop&copy GC the reasoning is unnecessary since all the objects will be allocated near each other anyhow. You avoid additional overhead for each single dimension though, so you use your memory and cache a bit better.
For some algorithms it's nicer to just use a one dimensional array which may make the code shorter and slightly faster - that's probably the one thing that can be argued as subjective here.
I think that if you need a 2D array, is because you would like to access it as a 2d array, not as a 1D array
Otherwise you can do a simple multiply to make it a 1D array
If I was to use a 2-D array, I would vote for matrix[i][j]. I think this is more readable. However, I might consider using Guava's Table class.
http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Table.html
I don't think that your "favourite" way, or the most aesthetically pleasing way is a good approach to take with this issue - underlying performance would be my main concern.
Storing a matrix as a contiguous array is often the most efficient way of doing matrix calculations. If you take a look at optimised BLAS (Basic Linear Algebra Subroutine) libraries, such as the Intel MKL, the AMD ACML, ATLAS etc etc contiguous matrix storage will be used. When contiguous storage is used, and contiguous data access patterns are exploited higher performance can result due to the improved locality-of-reference (i.e. cache performance) of the operations.
In some languages (i.e. c++) you could use operator overloading to achieve the data[i][j] style of indexing while doing the 1D array index mappings behind the scenes.
Hope this helps.

Categories

Resources