Hi. I'm trying to create a Traffic simulator and I'm stuck on how to get a Car object to turn into a road. I've managed to have a car go straight (which is really easy anyway lol) but I can't really find a way to get it to turn into a road, specifically a left turn.

The code I have currently is this:

import java.applet.*;
import java.awt.*;
import java.awt.geom.AffineTransform;


public class Traffic3 extends Applet implements Runnable
{
	//thread variables
	 Thread t;
	 int i;
	 //double buffer variables
	 Image offscreenImage;
	 Graphics offscr;
	 int width;
	 int height;
	 
	 //car
	 //coordinates for lanes
	 //south road, left lane
	 int sLeftX = 232;	 
	 int sLeftY = 570;
	 Car car = new Car(sLeftX,sLeftY);
	 	 
	  public void init()
	  {		  
		  this.setSize(600,600);
		  
		  //thread stuff
	      t = new Thread(this);
	      t.start();

	    i = 0;
	    //double buffer stuff
	    width = size().width;
	    height = size().height;

	    offscreenImage = createImage(width, height);
	    offscr = offscreenImage.getGraphics();	    
	  }

	  public void run()
	  {
	    while(true)
	    {
	    this.requestFocus();
	      i++;
	      //straight
	      //sLeftY-=5;	      
	      //car.changePosition(sLeftY);	      
	      //if (sLeftY == -63)
	    	  //sLeftY=557;
	      
	      //left
	      sLeftY-=5;	      
	      car.changePosition(sLeftY);	      
	      if (sLeftY == 365)	    	  
	      {
	    	  car.rotatePosition();
	    	  
	    	  sLeftY=570;
	    	  //for (i=0;i<10;i++)
	    	  //{
//	    		  car.iX[1] += 1;
//	    		  car.iY[1] -= 1;
//	    		  car.iX[2] += 1;
//	    		  car.iY[2] -= 1;
//	    		  car.iX[3] -= 1;
//	    		  car.iY[3] -= 1;
	    	  //}
	      } 	
	      repaint();
	      
	      try {
	        t.sleep(1000/30);
	      } catch (InterruptedException e) { ; }
	    }
	  }

	  public void paint(Graphics g)
	  {
	    //buffer stuff
	    offscr.setColor(Color.black);
	    offscr.fillRect(0, 0, width, height);
	    
	    offscr.setColor(Color.blue);
	    offscr.drawString("i = "+i,10,20);
	    roads(offscr);	    		
		
		car.paint(offscr);
		

	    g.drawImage(offscreenImage, 0, 0, this);
	  }
	  //update for buffer
	  public void update(Graphics g)
	  {
	    paint(g);
	  }

	  void roads(Graphics g)
	 	{
	    	 //Roads
	    	 //west	    	
	    	 g.setColor(Color.gray);
	    	 g.fillRect(0, 220, 220, 150);
	    	 g.setColor(Color.black);
	 		
	 		//north	 		
	    	 g.setColor(Color.gray);
	    	 g.fillRect(220, 0, 150, 220);
	    	 g.setColor(Color.black);
	    	 
	    	 //east	 		
	    	 g.setColor(Color.gray);
	    	 g.fillRect(370, 220, 220, 150);
	    	 g.setColor(Color.black);
	    	 
	    	 //south
	 		 g.setColor(Color.gray);
	    	 g.fillRect(220, 370, 150, 220);
	    	 g.setColor(Color.black);
	 		
	    	 //middle square
	    	 g.setColor(Color.gray);
	    	 g.fillRect(220, 220, 150, 150);
	    	 	    	 
	    	 //north and south dividers
	    	 g.setColor(Color.white);	 
	    	 
	    	 for(int j=0;j<30;j++)	    	  
	    	 {	    		  
	    		 if (j!=11 && j!=12 && j!=13 && j!=14 && j!=15 && j!=16 && j!=17 && j!=18)	 	  
	    		 {     			 
	    			 g.drawLine(270,j*20,270,j*20+10);		    			  
	    			 g.drawLine(320,j*20,320,j*20+10);	 	    		  
	    		 }	    	  
	    	 }
	    	 //east and west dividers	    	  
	    	 for(int i=0;i<30;i++)		    	  
	    	 {	    		  
	    		 if (i!=11 && i!=12 && i!=13 && i!=14 && i!=15 && i!=16 && i!=17 && i!=18)		    	   
	    		 {	
	    			 g.drawLine(i*20,270,i*20+10,270);	 
	    			 g.drawLine(i*20,320,i*20+10,320);		    	   
	    		 }		    	  
	    	 }	 	
	 	}
	  public class Car {
    	  private float sfCarLength;
    	  private Color cColor;
    	  private int posX;
    	  private int posY;
    	  
    	  private float sfX[] = new float[4];    	    
    	  private float sfY[] = new float[4];
    	  private int iX[] = new int[4];      // Integer arrays for constructing the polygon for painting
    	  private int iY[] = new int[4];
    	  private float sfPaintScaleFactor;
    	  
    	  Polygon pgon2;

    	  
    	  public Car(int x, int y) 
    	  {
    		  cColor = Color.blue;    
    		  posX = x;
    		  posY = y;
    		  
    		  iX[0] = 0; iY[0] = 0;
    	      iX[1] = 0; iY[1] = 25;
    	      iX[2] = 20; iY[2] = 25;
    	      iX[3] = 20; iY[3] = 0;
    	  }
    	
    	  public void paint(Graphics g) 
    	  {	  
    		  Polygon pgon;
    	      pgon = new Polygon(iX, iY, 4);
    	      pgon.translate(posX, posY);
    	      g.setColor(cColor);
    	      g.fillPolygon(pgon);
    	      g.setColor(Color.black);
    	      g.drawPolygon(pgon);
    	      
    	      
    	      pgon2 = new Polygon(iX, iY, 4);
    	      pgon2.translate(232, 365);
    	      g.setColor(cColor);
    	      g.fillPolygon(pgon2);
    	      g.setColor(Color.black);
    	      g.drawPolygon(pgon2);
    	  }
    	      	    	      	  
    	  public void changePosition(int y)
    	  {
    		  this.posY = y; 
    		  repaint();
    	  }
    	  
    	  public void rotatePosition()
    	  {    		     		  
    		  AffineTransform tx = new AffineTransform();
    		  		  
    		  tx.rotate(30.0 * Math.PI / 180.0);
    		  Shape newShape = tx.createTransformedShape(pgon2);

    		  //pgon2.rotate(30.0 * Math.PI / 180.0);
    		  repaint();
    	  }
      }  	 
	}

The rotatePosition() method is just something i tried doing but failed miserably. Any ideas on the best approach to take?

Thanks.

Edited 6 Years Ago by shakssage: n/a

You have 4 possible directions: N,E,S,W.
Implement them as boolean values.
In your code N=true, E=S=W=false.
Inside method check this N,E,S,W values.

public void run() {
        while (true) {
            this.requestFocus();
            i++;
            if (N) {
                sLeftY -= 5;
                car.changePositionY(sLeftY); // same as your current method car.changePosition
            } else if (E) {
                sLeftX -= 5;
                car.changePositionX(sLeftX); // write a new one 
            } else if (S) {
                //TODO
            } else {//W
                //TODO
            }

            if (sLeftY == 365) {
                car.rotatePosition();
                N = false;
                W = false;
                S = false;
                E = true;

                sLeftY = 570;
            }
            // other conditions
            repaint();
            ...

Hmm, I think I understand what you're saying but my main problem was getting the car onto the turn. So how should I simulate the car turning into the left lane, for example?
I kind of need the car to move in a curve while turning which I don't know how to do. I've had a look at affinetransform and changing the polygon values but they seem to not work.

Make your method rotatePosition() same as changePosition method with angle parameter.
Use Graphics 2D.
Treat same all transformations.
Reply, where is your center of car? (dimensions of car)
Where is your center of rotation? (turning radius)
Before rotating of car you need somthing translate it. After rotating return to previous values.
Here is car's paint method:

public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;

            Polygon pgon = new Polygon(iX, iY, 4);

            AffineTransform tx = new AffineTransform();
            int dx = -20;
            int dy = 0;
            tx.translate(posX + dx, posY + dy);
            //tx.translate(posX, posY);
            tx.rotate(angle);
            tx.translate(-dx, -dy);
            Shape pgonT = tx.createTransformedShape(pgon);
            g2.setColor(cColor);
            g2.fill(pgonT);
            g2.setColor(Color.black);
            g2.draw(pgonT);
        }

Thanks for the help, but I am now officially confused lol.
Ok, so atm with the code you gave me so far. The car starts moving and once it gets to y-position 365, it stops, because boolean E is now true. If boolean E is true it executes the changePositionX method, which is currently empty, thus the car is stationary.
Now what I need to do is rotate the car whilst it is turning into the road right?

I'm not sure what you mean by dimensions or how to find it because I created the car using polygons. The centre of rotation would be the middle of the car?
Translating the car would mean to move the car to a different position, however after the rotation, since the car is a rectangle, if it is returned to it's original values, it would look wrong.

Sorry. I don't quite understand how to do it.

OK. Step by step:

the changePositionX method, which is currently empty

My recommendations from "Two dimensions: X&Y":
Line 7:car.changePositionY(sLeftY); // same as your current method car.changePosition
Line 10:car.changePositionX(sLeftX); // write a new one
My recommendations from "AffineTransform, Graphics 2D":
Make your method rotatePosition() same as changePosition method with angle parameter.

public void run() {
        while (true) {
            this.requestFocus();
            i++;
            /////////
            {// the best way is put this code with N,E,S,W,R values into Car class
                // in the method car.go();
                // here should be invocation of method:  car.go();
//REALIZE of STATE
                if (N) {
                    sLeftY -= 1;
                    car.changePositionY(sLeftY);
                } else if (E) {
                    sLeftX -= 1;
                    car.changePositionX(sLeftX);
                } else if (S) {
                    //TODO
                } else if (W) {
                    //TODO
                } else if (R) {
                    sRot -= 1;
                    car.changeRot(sRot);
                }
//CHANGE of STATE
//boundary conditions
                if (sLeftY == 365) {
                    // condition for end of car go straight 
                    N = false;
                    W = false;
                    S = false;
                    E = false;
                    R = true;
                }
                if (sRot == -90) {
                    // condition for end of car left rotation 
                    N = false;
                    W = false;
                    S = false;
                    E = true;
                    R = false;
                }
                if (sLeftX <= 24) {
                    // condition for end of car simulation (do nothing-for example)
                    N = false;
                    W = false;
                    S = false;
                    E = false;
                    R = false;
                }

                // other conditions
            }
            /////////
            repaint();

            try {
                t.sleep(1000 / 100);//30
            } catch (InterruptedException e) {
                //
            }
        }
    }

class Car

public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            Polygon pgon = new Polygon(iX, iY, 4);

            AffineTransform tx = new AffineTransform();
            int dx = -30;//-10;//0; 
            int dy = 0;
            tx.translate(posX + dx, posY + dy);
            // tx.translate(posX, posY);
            tx.rotate(Math.toRadians(angle));
            tx.translate(-dx, -dy);

            Shape pgonT = tx.createTransformedShape(pgon);
            g2.setColor(cColor);
            g2.fill(pgonT);
            g2.setColor(Color.black);
            g2.draw(pgonT);

            //visualisation of current x,y translate values
            int xx = (int) tx.getTranslateX();
            int yy = (int) tx.getTranslateY();
            g2.setColor(Color.red);
            g2.fillOval(xx - 2, yy - 2, 4, 4);
            //
        }

There are two different things about centres.
One: center of car. In your case center of car is in Point(0,0)
//centered car - center of car is in Point(0,0)
iX[0] = -10;//0;
iY[0] = -12;//0;

iX[1] = -10;//0;
iY[1] = 12;//25;

iX[2] = 10;//20;
iY[2] = 12;//25;

iX[3] = 10;//20;
iY[3] = -12;//0;

Two: center of rotation of car. The centre of car can be a center of rotation. In this case car rotates in place (radius of rotation equals zero). Better way is use real values from real cars (6-12 meters).

Woohoo, it worked! The car turned into the road, now all I have to do is fiddle with it and make it carry on, it shouldn't be a problem.
Thank you very much for your help. Once again, there are many great programmers here.
I'm gonna leave this thread open a bit longer incase I get into some more trouble with the car movement.
Thanks again.

This question has already been answered. Start a new discussion instead.