Reputation: 479
I'll try to explain my problem: I'm working with a 3D environment, I have two adjacent points (for example A: 1,1,1 and B: 2,1,1) and I need a method to find all 8 or 6 points that are neighboring to B. I can do this on paper but I cannot find a way to do this in the program, unless I specify it point by point manually (pretty annoying and long since it's 18*8 + 8*6 different cases).
I did the calculations by hand and the results are in my example: 2,1,0; 2,2,0; 2,0,1; 2,0,2; 2,1,2; 2,2,1; 2,2,2; 2,0,0
Another example has A: 1,1,1 and B: 2,2,1 with the following results: 2,1,1; 1,2,1; 2,1,2; 1,2,2; 2,1,0; 1,2,0; 2,2,2; 2,2,0
A third one would be A: 1,1,1 and B 2,2,2: 2,2,1; 2,1,2; 1,2,2; 1,1,2; 1,2,1; 2,1,1
Upvotes: 0
Views: 65
Reputation: 479
public List<RPoint> TDNeighborsOnALine(RPoint endPoint){
List<RPoint> points = new ArrayList<>();
if (Geometry.distanceTwoPoints(this, endPoint) > 1){
int vx = Math.max(-1, Math.min(1, (endPoint.getX()-x)));
int vy = Math.max(-1, Math.min(1, (endPoint.getY()-y)));
int vz = Math.max(-1, Math.min(1, (endPoint.getZ()-z)));
RPoint b = new RPoint (x + vx, y + vy, z + vz);
RPoint c = new RPoint (x + (vx*2), y + (vy*2), z + (vz*2));
for (int ox = -1; ox < 2; ox++){
for (int oy = -1; oy < 2; oy ++){
for (int oz = -1; oz < 2; oz++){
RPoint p = new RPoint(ox + x, oy + y, oz + z);
double d = Geometry.distanceTwoPoints(c, p);
if (d < Geometry.distanceTwoPoints(c, this) && d <= 3){
points.add(p);
}
}
}
}
} else {
points.add(endPoint);
}
return points;
}
public static double distanceTwoPoints(RPoint a, RPoint b){
return Math.sqrt(Math.pow((a.getX() - b.getX()), 2) + Math.pow((a.getY() - b.getY()), 2) + Math.pow((a.getZ() - b.getZ()), 2));
}
This is my solution to the problem. It works by relying on the fact that each neighbour to A that is at a lesser distance from C than C is to A, where C is the mirror of A on B, is a point on the path from A to C, each neighbour to A whose distance from C is farther than 3 is not a convenient point on the path either, because it's removed more than x,y,z from C.
Upvotes: 0
Reputation: 3464
i have had to solve such problems on a 2d map (but it's just the same in 3d)
public Point[] getNeigbours(Point from, Point to){
EForm form = determineForm(from, to);
if (form == EForm.formA){
Point n1 = new Point(from.x, from.y, from.z+1);
Point n2 = new Point(from.x, from.y, from.z-1);
//...and so on
Point nn = new Point(from.x-1, from.y-1, from.z-1);
Point[] retValue = new Point[]{n1, n2, ... nn};
return retValue;
}
if (form == EForm.formB){
Point n1 = // another rule applys for this form
Point[] retValue = new Point[]{n1, n2, ... nn};
return retValue;
}
}
private EForm determineForm(Point from, Point to){
int dx = to.x-from.x;
int dy = to.y-from.y;
int dz = to.x-from.z;
if (dx == 0 && dx == -1 && dz == 0){
return EForm.formA;
}
}
so you have first determine the form of you Point-Combination; there should be only 14 possible forms for those two point;
then you have to manually detect all the neighbours for each form; finally if you know them all, you can create your neighbours (using you manually created solutions);
EForm is an Enum, containg those 14 possible forms!
Upvotes: 1