Angelo Alvisi
Angelo Alvisi

Reputation: 479

Finding a set of specific neighboring points (not the whole of them) given two different 3D points

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

Answers (2)

Angelo Alvisi
Angelo Alvisi

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

Martin Frank
Martin Frank

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

Related Questions