1
votes

I am a first year computer programming student working on a project of Robots and Robot testing environment. Although I'm new to Stackoverflow, I'm pretty aware that we are not supposed to help with assignments or homework. I'm struggling to understand why such behavior is happening, so it would be really helpful just to understand why it's happening.

We are using Processing libraries to program in Java. Our task is to create a robot testing environment and create three robots performing different movements.

The movement I'm trying to program is Patrol, which means just go around the edges of the screen. The expected behavior is to go forward until it reaches a wall, turn left (90 degrees counter-clock wise), and go forward again. This project is in conjunction with our Math class. That being said, we can't use methods like rotate(), translate(), pushMatrix() and popMatrix() to help rotating the forms (each robot is a triangle).

So, the steps I followed to rotate the triangles were: 1) translate its center point to the origin (0,0) and the vertices using the same translation; 2) rotate all points, where (x, y) become (y, -x); 3) translate back to correct position (inverse of the step 1 translation).

I set some boundaries if statements to put the triangle back to screen if, after rotation, anything went off screen.

My problem
After turning, the triangle is appearing in strange position, like teleporting.

I added a few lines so we can get each vertex's coordinates, the direction it's going and detect when direction is changed.

Code
There are two files: TestRobots, Robot.

Robot:

import processing.core.PApplet;

public class Robot{
    int colour;
    String name;
    float width;
    float height;
    float x1;
    float y1;
    float x2;
    float y2;
    float x3;
    float y3;
    int direction;
    int speed;
    float centralPointX = width/2;
    float centralPointY = height/2;
    PApplet parent;

    public Robot(PApplet parent, String name, int colour, float x1, float y1, float x2, float y2, float x3, float y3, int speed){
        this.parent = parent;
        this.name = name;
        this.colour = colour;
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.x3 = x3;
        this.y3 = y3;
        this.speed = speed;
        direction=4;

        width = x2-x3;
        if (width < 0){
            width *= -1;
        }
        if (y2 > y3){
            height = y2-y1; 
        }else{
            height = y3-y1;
        }
        if (height < 0){
            height *= -1;
        }

        if (y1<y2 && y1<y3){
            direction=4;
        }
    }

    public void drawRobot(){
        parent.fill(colour);
        parent.triangle(x1, y1, x2, y2, x3, y3);
        parent.ellipseMode(parent.CENTER);
        parent.ellipse(x1, y1, 3, 3);   
    }

    public void moveForward(){
        if(x1<parent.width || y1 <parent.height || x1 > 0 || y1 > 0){                   
            switch (direction){
                case 1:
                    x1 += speed;
                    x2 += speed;
                    x3 += speed;
                    break;
                case 2:
                    y1 += speed;
                    y2 += speed;
                    y3 += speed;
                    break;
                case 3:
                    x1 -= speed;
                    x2 -= speed;
                    x3 -= speed;
                    break;
                case 4:
                    y1 -= speed;
                    y2 -= speed;
                    y3 -= speed;
                    break;
            }
        }
    }

    public void turnLeft(){
        //Store original coordinates.
        float tempX1 = x1;
        float tempY1 = y1;
        float tempX2 = x2;
        float tempY2 = y2;          
        float tempX3 = x3;
        float tempY3 = y3;

        //Calculate translation of the central point of triangle to the origin.
        float xTranslation = 0 - centralPointX;
        float yTranslation = 0 - centralPointY;

        //Translate all points by the translation calculated.
        float translatedX1 = tempX1 + xTranslation;
        float translatedY1 = tempY1 + yTranslation;
        float translatedX2 = tempX2 + xTranslation;
        float translatedY2 = tempY2 + yTranslation;
        float translatedX3 = tempX3 + xTranslation;
        float translatedY3 = tempY3 + yTranslation;

        //Rotate all points 90 degrees counterclockwise, (x, y) -->  (y, -x).
        float rotatedX1 = translatedY1;
        float rotatedY1 = -translatedX1;
        float rotatedX2 = translatedY2;
        float rotatedY2 = -translatedX2;
        float rotatedX3 = translatedY3;
        float rotatedY3 = -translatedX3;

        //Translate all points back.
        x1 = rotatedX1 - xTranslation;
        y1 = rotatedY1 - yTranslation;
        x2 = rotatedX2 - xTranslation;
        y2 = rotatedY2 - yTranslation;
        x3 = rotatedX3 - xTranslation;
        y3 = rotatedY3 - yTranslation;

        //Check which y and which x are the smallest, in order to correct any negative numbers.
        float minX;
        float minY;
        if (y1<y2 && y1<y3){
            minY = y1;
        } else if (y2<y1 && y2<y3){
            minY = y2;
        } else {
            minY = y3;
        }
        if (x1<x2 && x1<x3){
            minX = x1;
        } else if (x2<x1 && x2<x3){
            minX = x2;
        } else {
            minX = x3;
        }

        //Check which y and which x are the biggest, in order to correct any out-of-screen draws.
        float maxX;
        float maxY;
        if (y1>y2 && y1>y3){
            maxY = y1;
        } else if (y2>y1 && y2>y3){
            maxY = y2;
        } else {
            maxY = y3;
        }
        if (x1>x2 && x1>x3){
            maxX = x1;
        } else if (x2>x1 && x2>x3){
            maxX = x2;
        } else {
            maxX = x3;
        }       

        //Correct position if any coordinate is negative.
        if((minY-speed)<=minY){
            float differenceY = -minY + 10;
            y1 += differenceY;
            y2 += differenceY;
            y3 += differenceY;
        } 
        if(x1<=(x1-speed)){
            float differenceX = -minX + 10;
            x1 += differenceX;
            x2 += differenceX;
            x3 += differenceX;
        } 

        //Correct position if any coordinate is bigger than the screen size.
        if((parent.height<=(maxY+speed))){
            float differenceY = (-maxY+parent.height) + 10;
            y1 -= differenceY;
            y2 -= differenceY;
            y3 -= differenceY;
        } 
        if((x1+speed)>=parent.width){
            float differenceX = (-maxX+parent.width) + 10;
            x1 -= differenceX;
            x2 -= differenceX;
            x3 -= differenceX;
        } 

        //Change direction variable and adjust it between 0 and 4.
        direction -=1;
        if (direction == 0){
            direction = 4;
        }   
    }

    public void patrol(){
        System.out.println("Direction is: "+ direction);
        if(((y1-speed)<= 0)||((y1+speed)>= parent.height) || ((x1+speed)>=parent.width)||((x1-speed)<=0)){
            turnLeft();
            System.out.println("The NEW direction is: "+ direction);
        }
        moveForward();
    }
}

TestRobots:

import processing.core.PApplet;

public class TestRobots extends PApplet{
    Robot alice = new Robot(this, "Alice", 255, 257f, 389f, 309f, 450f, 209f, 450f, 3);

    public static void main(String[] args){
        PApplet.main("TestRobots");
    }

    public void settings(){
        size(1000, 500);
    }

    public void setup(){
        frameRate(30);      
    }

    public void draw(){
        background(255);
        alice.patrol();
        System.out.println("x1 = "+ alice.x1);
        System.out.println("y1 = "+ alice.y1);

        System.out.println("x2 = "+ alice.x2);
        System.out.println("y2 = "+ alice.y2);

        System.out.println("x3 = "+ alice.x3);
        System.out.println("y3 = "+ alice.y3);

        alice.drawRobot();  
    }
}

Here is a print of the generated output. I snipped the part where it changes direction:

Direction is: 2
x1 = 62.0
y1 = 497.0
x2 = 10.0
y2 = 436.0
x3 = 110.0
y3 = 436.0

The NEW direction is: 1
x1 = 500.0
y1 = 58.0
x2 = 439.0
y2 = 110.0
x3 = 439.0
y3 = 10.0

Same strange behavior here:

Direction is: 4
x1 = 257.0
y1 = 2.0
x2 = 309.0
y2 = 63.0
x3 = 209.0
y3 = 63.0

The NEW direction is: 3
x1 = -1.0
y1 = 62.0
x2 = 60.0
y2 = 10.0
x3 = 60.0
y3 = 110.0

The NEW direction is: 2
x1 = 62.0
y1 = 74.0
x2 = 10.0
y2 = 13.0
x3 = 110.0
y3 = 13.0

Thank you very much for reading until here and sorry in advance if I wasn't clear enough. It's my first question!

Gustavo

1
Please edit your code to reduce it to a minimal reproducible example of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility.Toby Speight

1 Answers

1
votes

I think your problem relates to the variables centralPointX and centralPointY. Look at this code you wrote:

//Calculate translation of the central point of triangle to the origin.
float xTranslation = 0 - centralPointX;
float yTranslation = 0 - centralPointY;

//Translate all points by the translation calculated.
float translatedX1 = tempX1 + xTranslation;
float translatedY1 = tempY1 + yTranslation;
float translatedX2 = tempX2 + xTranslation;
float translatedY2 = tempY2 + yTranslation;
float translatedX3 = tempX3 + xTranslation;
float translatedY3 = tempY3 + yTranslation;

It seems from this that you think centralPointX and centralPointY indicate the center of the triangle... However, look at where they are defined:

float centralPointX = width/2;
float centralPointY = height/2;

So they don't actually represent the center xy co-ordinates. What you need to do is fix this part:

//Calculate translation of the central point of triangle to the origin.
float xTranslation = 0 - centralPointX;
float yTranslation = 0 - centralPointY;

So that it actually does what the comment says it should do, i.e., calculates the x and y co-ordinates of the center of your triangle.

I won't implement this for you, because as you said, it is homework. However, I think this should definitely point you in the right direction. Also, keep up the good work. I wish every first question was as well thought out as this.