/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package robotinterface.robot.simulation;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Locale;
import robotinterface.robot.device.IRProximitySensor;
import robotinterface.util.LineIterator;
/**
*
* @author antunes
*/
public class Environment {
private final ArrayList<Line2D.Double> followLines = new ArrayList<>();
private final ArrayList<Line2D.Double> walls = new ArrayList<>();
private final ArrayList<Line2D.Double> followLinesTmp = new ArrayList<>();
private final ArrayList<Line2D.Double> wallsTmp = new ArrayList<>();
private final ArrayList<double[]> wallsData = new ArrayList<>();
private final ArrayList<double[]> followLinesData = new ArrayList<>();
private static final Color obstacleColor = Color.decode("#BA9C3A");
public static Color getObstacleColor() {
return obstacleColor;
}
public Environment() {
}
@Deprecated
private void alienCode() {
HashMap<Character, Integer> map = new HashMap<>();
map.put(' ', 0);
map.put('t', 1);
map.put('e', 2);
map.put('r', 4);
map.put('s', 8);
map.put('o', 16);
String str = "terrestres terrosos";
int i = 0;
for (char c : str.toCharArray()) {
addCodedLetter(i, map.get(c));
i++;
}
}
@Deprecated
private void addCodedLetter(int index, int code) {
double w = 50;
double x = index * 80 + 60;
for (int i = 0; i < 5; i++) {
if ((code & (1 << i)) != 0) {
double h = i * 7 - 14;
addFollowLine(new double[]{x, h, x + w, h});
}
}
}
public void addWall(double[] line) {
wallsData.add(line);
walls.add(new Line2D.Double(line[0], line[1], line[2], line[3]));
}
public void addFollowLine(double[] line) {
followLinesData.add(line);
followLines.add(new Line2D.Double(line[0], line[1], line[2], line[3]));
}
public void removeWall(Shape s) {
int i = walls.indexOf(s);
if (i != -1) {
wallsData.remove(i);
}
}
public void removeFollowLine(Shape s) {
int i = followLines.indexOf(s);
if (i != -1) {
followLinesData.remove(i);
}
}
public void saveFile(File file) throws IOException {
FileWriter fw = new FileWriter(file.getAbsoluteFile());
StringBuilder sb = new StringBuilder();
NumberFormat format = NumberFormat.getInstance(Locale.US);
format.setGroupingUsed(false);
if (format instanceof DecimalFormat) {
((DecimalFormat) format).applyPattern("#.00");
}
sb.append("# Environment ").append(System.currentTimeMillis()).append(" #\n");
if (!wallsData.isEmpty()) {
sb.append("# Obstacles #\n");
sb.append("\n");
for (double[] data : wallsData) {
sb.append("wall(").append(format.format(data[0])).append(", ").append(format.format(data[1])).append(", ").append(format.format(data[2])).append(", ").append(format.format(data[3])).append(")\n");
}
sb.append("\n");
}
if (!followLinesData.isEmpty()) {
sb.append("# Followable Lines #\n");
sb.append("\n");
for (double[] data : followLinesData) {
sb.append("line(").append(format.format(data[0])).append(", ").append(format.format(data[1])).append(", ").append(format.format(data[2])).append(", ").append(format.format(data[3])).append(")\n");
}
}
sb.append("\n");
fw.write(sb.toString());
fw.close();
}
public void loadFile(InputStream input) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("#") && !line.trim().isEmpty()) {
String str = line.substring(line.indexOf("(") + 1, line.indexOf(")"));
String[] argv = str.split(",");
if (line.contains("wall") && argv.length == 4) {
argv[0] = argv[0].trim();
argv[1] = argv[1].trim();
argv[2] = argv[2].trim();
argv[3] = argv[3].trim();
double x1 = Double.parseDouble(argv[0]);
double y1 = Double.parseDouble(argv[1]);
double x2 = Double.parseDouble(argv[2]);
double y2 = Double.parseDouble(argv[3]);
addWall(new double[]{x1, y1, x2, y2});
} else if (line.contains("line") && argv.length == 4) {
argv[0] = argv[0].trim();
argv[1] = argv[1].trim();
argv[2] = argv[2].trim();
argv[3] = argv[3].trim();
double x1 = Double.parseDouble(argv[0]);
double y1 = Double.parseDouble(argv[1]);
double x2 = Double.parseDouble(argv[2]);
double y2 = Double.parseDouble(argv[3]);
addFollowLine(new double[]{x1, y1, x2, y2});
}
}
}
reader.close();
}
public double beamDistance(double x, double y, double theta, double d) {
double df = IRProximitySensor.MAX_DISTANCE;
double dt;
double x2 = x + IRProximitySensor.MAX_DISTANCE * cos(theta);
double y2 = y + IRProximitySensor.MAX_DISTANCE * sin(theta);
Line2D.Double line = new Line2D.Double(x, y, x2, y2);
Point2D p;
wallsTmp.clear();
wallsTmp.addAll(walls);
for (Line2D.Double wall : wallsTmp) {
Line2D.Double tmpLine = new Line2D.Double();
for (Iterator<Point2D> lineIt = new LineIterator(line); lineIt.hasNext();) {
p = lineIt.next();
tmpLine.setLine(x, y, p.getX(), p.getY());
if (tmpLine.intersectsLine(wall)) {
dt = sqrt(pow(x - p.getX(), 2) + pow(y - p.getY(), 2)) - d;
if (df > dt && dt > 0) {
df = dt;
}
}
}
}
return df / 2;
}
public boolean isOver(double x, double y) {
followLinesTmp.clear();
followLinesTmp.addAll(followLines);
for (Shape s : followLinesTmp) {
if (s.intersects(x - 3, y - 3, 6, 6)) {
return true;
}
}
return false;
}
public void draw(Graphics2D g) {
Stroke str = g.getStroke();
g.setStroke(new BasicStroke(5));
g.setColor(Color.BLACK);
for (Shape s : followLines) {
g.draw(s);
}
g.setColor(obstacleColor);
for (Shape s : walls) {
g.draw(s);
}
g.setStroke(str);
}
public Iterator<Line2D.Double> linesIterator() {
return followLines.iterator();
}
public Iterator<Line2D.Double> obstaclesIterator() {
return walls.iterator();
}
public void clearEnvironment() {
wallsData.clear();
walls.clear();
followLinesData.clear();
followLines.clear();
}
}