All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.marvinproject.image.render.lindenmayer.TurtleGraphics Maven / Gradle / Ivy

The newest version!
/**
Marvin Project <2007-2013>
http://www.marvinproject.org

License information:
http://marvinproject.sourceforge.net/en/license.html

Discussion group:
https://groups.google.com/forum/#!forum/marvin-project
*/

package org.marvinproject.image.render.lindenmayer;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.util.Stack;

import marvin.image.MarvinImage;

/**
 * @author Gabriel Ambr�sio Archanjo
 */
public class TurtleGraphics {

	private double walkDistance;
	private double rotationAngle;
	private int startPx;
	private int startPy;
	private double startAngle;
	
	// Current Turtle State
	private double currentPx;
	private double currentPy;
	private double currentAngle;
	
	// State Stack
	private Stack stateStack;
	
	private Polygon polygon = new Polygon();
	private boolean drawingPolygon = false;
	
	public TurtleGraphics(){
		stateStack = new Stack();		
	}
	
	private void reset(){
		currentPx = 0;
		currentPy = 0;
		currentAngle = startAngle;
		stateStack.clear();
	}
	
	public void setStartPosition(int x, int y, double angle){
		startPx = x;
		startPy = y;
		startAngle = angle;
	}
	
	public void setWalkDistance(double distance){
		walkDistance = distance;
	}
	
	public void setRotationAngle(double angle){
		rotationAngle = angle;
	}
	
	public void render(String text, Grammar grammar, int iterations, MarvinImage image){
		
		reset();
		
		for(int i=0; i maxX){	maxX = currentPx;	};
							if(currentPy < minY){	minY = currentPy;	};
							if(currentPy > maxY){	maxY = currentPy;	};
						}
					}
					else{
						polygon.addPoint(((int)newPx+startPx), (int)(newPy+startPy));
						
					}
					
					currentPx = newPx;
					currentPy = newPy;
					break;
				}
				case 'g':
				case 'h':
				case 'j':
				case 'k':
				case 'l':
				{
					// do nothing
				}					
				case '+':
				{
					currentAngle -= rotationAngle;
					if(currentAngle < 0){
						currentAngle = 360+currentAngle;
					}
					break;
				}	
				case '-':
				{
					currentAngle = (currentAngle + rotationAngle)%360;
					break;
				}
				case '[':
				{
					stateStack.push(new Double[]{currentPx, currentPy, currentAngle});
					break;
				}
				case ']':
				{
					Double o[] = stateStack.pop();
					currentPx = o[0];
					currentPy = o[1];
					currentAngle = o[2];
					break;
				}
				case '{':
					polygon = new Polygon();
					drawingPolygon = true;
					break;
				case '}':
					//g.fillPolygon(p);
					drawingPolygon = false;
					//g.setColor(Color.black);
					//System.out.println("black");
					break;
				case '#':
					if(text.charAt(i+1) == '0'){
						//g.setColor(Color.black);
					}
					else if(text.charAt(i+1) == '1'){
						//g.setColor(new Color(0,100,0));
					}
					else if(text.charAt(i+1) == '2'){
						//g.setColor(Color.red);
					}
					else if(text.charAt(i+1) == '3'){
						//g.setColor(Color.yellow);
					}
					else if(text.charAt(i+1) == '4'){
						//g.setColor(Color.blue);
					}
					i++;
					break;
				case '&':
					//g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
					i++;
					break;
			}
		}
		
		int width = image.getWidth();
		int height = image.getHeight();
		
		if(currentPx < minX){	minX = currentPx;	};
		if(currentPx > maxX){	maxX = currentPx;	};
		if(currentPy < minY){	minY = currentPy;	};
		if(currentPy > maxY){	maxY = currentPy;	};
		
		double deltaX = Math.abs(maxX-minX);
		double deltaY = Math.abs(maxY-minY); 
		if(deltaX > deltaY){
			walkDistance = (width/deltaX);
			if(deltaY * walkDistance > height){
				walkDistance = walkDistance * (height/(deltaY * walkDistance));
			}
		}
		else{
			walkDistance = (height/deltaY);
			if(deltaX * walkDistance > width){
				walkDistance = walkDistance * (width/(deltaX * walkDistance));
			}
		}
		
		walkDistance *= 0.9;
		
		startPx = (int)((width/2)-((minX+((deltaX)/2))*walkDistance));
		startPy = (int)((height/2)-((minY+(deltaY/2))*walkDistance));
		
	}
	
	private void drawLine(int x0, int y0, int x1, int y1, MarvinImage image){
		boolean steep = (Math.abs(y1 - y0) > Math.abs(x1 - x0));
		int temp;
		if(steep){
			temp = x0;
			x0 = y0;
			y0 = temp;

			temp = x1;
			x1 = y1;
			y1 = temp;
		}
		if(x0 > x1){
			temp = x0;
			x0 = x1;
			x1 = temp;

			temp = y0;
			y0 = y1;
			y1 = temp;
		}

		int deltax = x1 - x0;
		int deltay = Math.abs(y1 - y0);
		int error = deltax / 2;
		int ystep;
		int y = y0;

		if(y0 < y1){
			ystep = 1;
		}
		else{
			ystep = -1;
		}

		for(int x=x0; x<=x1; x++){
         if(steep){
        	 	if(y >= 0 && y < image.getWidth() && x >= 0 && x < image.getHeight()){
        	 		image.setIntColor(y,x,0,0,0);
        	 	}
			}
			else{
				if(x >= 0 && x < image.getWidth() && y >= 0 && y < image.getHeight()){
					image.setIntColor(x,y,0,0,0);
				}
			}

         error = error - deltay;
         if (error < 0){
             y = y + ystep;
             error = error + deltax;
			}
		}
	}
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy