All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.barrybecker4.simulation.lsystem.rendering.LSystemRenderer Maven / Gradle / Ivy
// Copyright by Barry G. Becker, 2013. Licensed under MIT License: http://www.opensource.org/licenses/MIT
package com.barrybecker4.simulation.lsystem.rendering;
import com.barrybecker4.ui.util.ColorMap;
import com.barrybecker4.common.expression.TreeNode;
import com.barrybecker4.simulation.lsystem.model.expression.LExpressionParser;
import com.barrybecker4.ui.renderers.OfflineGraphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.List;
import static com.barrybecker4.simulation.lsystem.model.expression.LTokens.*;
/**
* Everything we need to know to compute the l-System tree.
* Should make the tree automatically center.
*
* @author Barry Becker
*/
public class LSystemRenderer {
private static final double LENGTH = 1.0;
private static final Color BG_COLOR = new Color(0, 30, 10);
private ColorMap cmap = new DepthColorMap();
private final int width;
private final int height;
private int numIterations;
private double angleIncrement;
private double scale;
private double scaleFactor;
private TreeNode root;
/** offline rendering is fast */
private final OfflineGraphics offlineGraphics_;
/** Constructor */
public LSystemRenderer(int width, int height, String expression,
int numIterations, double angleInc, double scale, double scaleFactor)
throws IllegalArgumentException {
this.width = width;
this.height = height;
this.numIterations = numIterations;
this.angleIncrement = angleInc * Math.PI / 180;
this.scaleFactor = scaleFactor;
LExpressionParser parser = new LExpressionParser();
try {
root = parser.parse(expression);
}
catch (Exception e){
throw new IllegalArgumentException(e.getMessage(), e);
}
this.scale = scale;
offlineGraphics_ = new OfflineGraphics(new Dimension(width, height), BG_COLOR);
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void reset() {
}
public BufferedImage getImage() {
return offlineGraphics_.getOfflineImage();
}
/**
* draw the tree
*/
public void render() {
offlineGraphics_.setColor(Color.RED);
OrientedPosition initialPosition = new OrientedPosition(width/2.0, height/8.0 - height, Math.PI/2.0);
double length = LENGTH * width / 10.0;
drawTree(initialPosition, length, root, numIterations, 0);
}
/**
* Draw the tree recursively.
* @param pos the position and angle in radians that the turtle graphics used when rotating '+' or '-'
*/
private void drawTree(OrientedPosition pos, double length, TreeNode tree, int numIterations, int depth) {
List list = new LinkedList(tree.children);
for (TreeNode child : list) {
if (child.hasParens) {
drawTree(new OrientedPosition(pos), scaleFactor * length, child, numIterations, depth + 1);
}
else {
String baseExp = child.getData();
for (int i = 0; i 0) {
drawTree(currentPos, length, root, numIterations - 1, depth);
}
else {
drawF(currentPos, length, depth);
}
}
else if (c == MINUS.getSymbol()) {
currentPos.angle -= angleIncrement;
}
else if (c == PLUS.getSymbol()) {
currentPos.angle += angleIncrement;
}
else {
throw new IllegalStateException("Unexpected char: "+ c);
}
}
private void drawF(OrientedPosition pos, double length, int num) {
int startX = (int) (pos.x);
int startY = - (int) (pos.y);
pos.x += scale * length * Math.cos(pos.angle);
pos.y += scale * length * Math.sin(pos.angle);
int stopX = (int) (pos.x);
int stopY = - (int) (pos.y);
offlineGraphics_.setColor(cmap.getColorForValue(num));
offlineGraphics_.drawLine(startX, startY, stopX, stopY);
int radius = (int)(scale * (length-0.4)/10);
offlineGraphics_.fillCircle(stopX, stopY, radius);
}
}