David Ortiz
David Ortiz

Reputation: 995

Iterating over diagonals and axis of a given origin - java

I'm facing a problem and I'd like to know some ideas on how to solve it. I have a matrix of two dimensions and given a point on that matrix I need to look for ten cells up, down right, left and with diagonal movements (see the following image).

enter image description here

What I'm doing is selecting the values of i and j as the values to be multiplied by the position coordinates and give the direction that I want in each case. For example:

And for the vertical and horizontal movements i and j will take values 1 or 0.

Having these two values I can take the center and add a value to it starting this value to 1 and increasing it until I get to the limit (10). If the center is (2,4) and I'm in diagonal A I will add the value that is starting in one multiplied by i and j for each coordinate having the following results:

Right now I am interested in computing i and j so that they take all the needed values for the diagonals and the axis. My java code that goes inside a loop is the following:

            GS.r++;
            if (GS.r > 10) {
                GS.r = 0;
                if (GS.iteration) {
                    int i = 0, j = 0;
                    if (GS.i == 1) {
                        i = -1;
                    } else if (GS.i == -1) {
                        i = 0;
                        j = 1;
                    }
                    if (GS.j == 1) {
                        j = -1;
                    } else if (GS.j == -1) {
                        j = 0;
                        i = 1;
                    }
                    GS.i = i;
                    GS.j = j;
                    if (GS.i == 1 && GS.j == 0) {
                        GS.iteration = false;
                        GS.i = -1;
                        GS.j = -1;
                    }
                } else {
                    if (GS.i == 1 && GS.j == 1) {
                        GS.iteration = true;
                        GS.i = 1;
                        GS.j = 0;
                    } else {
                        if (GS.i == 1)
                            GS.j *= -1;
                        GS.i *= -1;
                    }
                }

            }

GS.i and GS.j are initialised as -1. And with this code I get first the diagonals since the values for GS.i and GS.j would be (-1,-1) (1, -1) (-1, 1) (1, 1) and then the axis having these values: (-1, 0) (1, 0) (0, -1) (0, 1).

I was wondering if there is a better way of generating i and j since my code is not that clean.

Thank you!

Upvotes: 0

Views: 280

Answers (1)

StackFlowed
StackFlowed

Reputation: 6816

What I would do is create an enum for all the four directions you can move in that is Diagonal right up,Diagonal right down,Diagonal left up and Diagonal left down.

Sample code :

public enum Direction {
    DIAGONAL_RIGHT_UP(1,1),
    DIAGONAL_RIGHT_DOWN(1,-1),
    DIAGONAL_LEFT_UP(-1,1),
    DIAGONAL_LEFT_DOWN(-1,-1);

    public int x;
    public int y;

    private Direction(int xCoordinateChange,int yCoordinateChange) {
         x=xCoordinateChange;
         y=yCoordinateChange;
    }
}

Then use this to traverse.

public class CartesianCoordinate {
    private long xCoordinate;
    private long yCoordinate;

    public CartesianCoordinate(long xCoordinate,long yCoordinate) {
        this.xCoordinate=xCoordinate;
        this.yCoordinate=yCoordinate;
    }

    public long getXCoordinate() {
        return xCoordinate;
    }

    public long getYCoordinate() {
        return yCoordinate;
    }

    public void moveCoordinateByStepSize(Direction direction,long stepSize) {
        xCoordinate+=direction.x*stepSize;
        yCoordinate+=direction.y*stepSize;
    }

    @Override
    public int hashCode() {
        int hashCode=0;
        hashCode += (int)(xCoordinate-yCoordinate)*31;
        hashCode += (int)(yCoordinate+xCoordinate)*17;
        return hashCode;
    }

    @Override
    public boolean equals(Object object) {
        if(object == null || !(object instanceof CartesianCoordinate)) {
            return false;
        }
        if( this == object) {
            return true;
        }
        CartesianCoordinate cartesianCoordinateObject = (CartesianCoordinate)object;
        if(xCoordinate == cartesianCoordinateObject.getXCoordinate() && yCoordinate == cartesianCoordinateObject.getYCoordinate()) {
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
        return "["+xCoordinate+","+yCoordinate+"]";
    }

    public CartesianCoordinate getAClone() {
       return new CartesianCoordinate(xCoordinate,yCoordinate);
    }
}

Now say you have a point (1,3) as a starting point. what you can do is for 100 iterations in a particular line.

CartesianCoordinate startingPoint = new CartesianCoordinate(1,3);
CartesianCoordinate rightUpDiag = startingPoint.getAClone(),leftUpDiag = startingPoint.getAClone(),rightDownDiag = startingPoint.getAClone(),leftDownDiag = startingPoint.getAClone();
for(int counter = 0 ;counter < 100; counter ++) {
   System.out.println(rightUpDiag.moveCoordinateByStepSize(Direction.DIAGONAL_RIGHT_UP,1));
   System.out.println(leftUpDiag.moveCoordinateByStepSize(Direction.DIAGONAL_LEFT_UP,1));
   System.out.println(rightDownDiag.moveCoordinateByStepSize(Direction.DIAGONAL_RIGHT_DOWN,1));
   System.out.println(leftDownDiag.moveCoordinateByStepSize(Direction.DIAGONAL_LEFT_DOWN,1));
}

Upvotes: 3

Related Questions