package z11.example;
/**
*
* @author vietduc
*/
public class Simple2DConsoleDrawer {
public static class Point2D {
public Point2D(double x, double y) {
this.x = x;
this.y = y;
}
public double x;
public double y;
}
private static final boolean BLACK = true;
private static final boolean WHITE = false;
private boolean[] mapData; // a map of 0 or 1 value, 0: white, 1: black color
private final int mapWidth;
public static Point2D calculatePoint(Point2D center, double angle, double d) {
double x = center.x + d * Math.cos(angle);
double y = center.y + d * Math.sin(angle);
return new Point2D(x, y);
}
public static Point2D calculateRotatedPoint(Point2D centerPoint, double angle, Point2D point0) {
double s = Math.sin(angle);
double c = Math.cos(angle);
Point2D point = new Point2D(point0.x, point0.y);
// translate point back to origin:
point.x -= centerPoint.x;
point.y -= centerPoint.y;
// rotate point
double xnew = point.x * c - point.y * s;
double ynew = point.x * s + point.y * c;
// translate point back:
point.x = xnew + centerPoint.x;
point.y = ynew + centerPoint.y;
return point;
}
public Simple2DConsoleDrawer(int maxDimentionSizeValue) {
mapWidth = maxDimentionSizeValue;
mapData = new boolean[mapWidth * mapWidth];
}
private void drawPoint(double x, double y) throws Exception {
drawPoint(x, y, BLACK);
}
private void drawPoint(double x, double y, boolean value) throws Exception {
if (x >= mapWidth || x < 0) {
throw new Exception("x value out of map!");
}
if (y >= mapWidth || y < 0) {
throw new Exception("y value out of map!");
}
int intX = (int) Math.round(x);
int intY = (int) Math.round(y);
mapData[intY * mapWidth + intX] = value;
}
private void drawLine(Point2D point1, Point2D point2) throws Exception {
drawLine(point1.x, point1.y, point2.x, point2.y);
}
private void drawLine(double x1, double y1, double x2, double y2) throws Exception {
drawLine(x1, y1, x2, y2, BLACK);
}
private void drawLine(double x1, double y1, double x2, double y2, boolean value) throws Exception {
int intX1 = (int) Math.round(x1);
int intY1 = (int) Math.round(y1);
int intX2 = (int) Math.round(x2);
int intY2 = (int) Math.round(y2);
int dX = intX2 - intX1;
int dY = intY2 - intY1;
int dXAbs = Math.abs(dX);
int dYAbs = Math.abs(dY);
/*1.45 cause character in console is not a square-symbol*/
if (dXAbs > dYAbs * 1.45) {
for (int x = intX1; x != intX2; x += dX / dXAbs) {
double y = intY1 + Math.abs(x - intX1) * dY / (double) dXAbs;
drawPoint(x, y, value);
}
} else {
for (int y = intY1; y != intY2; y += dY / dYAbs) {
double x = intX1 + Math.abs(y - intY1) * dX / (double) dYAbs;
drawPoint(x, y, value);
}
}
}
public void printMapToStdOut() {
String lines = "";
for (int row = mapWidth - 1; row > 0; row--) {
String line = "";
for (int col = 0; col < mapWidth; col++) {
line += mapData[row * mapWidth + col] ? "*" : " ";
}
lines += line + System.lineSeparator();
}
System.out.println(lines);
}
public void clearMap() {
mapData = new boolean[mapWidth * mapWidth];
}
private void drawStar(int size) {
try {
int numofedgle = 5;
Point2D centerPoint = new Point2D(mapWidth / 2, mapWidth / 2);
Point2D[] points = new Point2D[numofedgle];
for (int i = 0; i < numofedgle; i++) {
points[i] = calculatePoint(centerPoint, Math.toRadians(90 + 360. / numofedgle * i), size);
}
for (int i = 0; i < numofedgle; i++) {
drawLine(points[i].x, points[i].y, points[(i + 2) % numofedgle].x, points[(i + 2) % numofedgle].y);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void drawSnowEdge(Point2D point1, Point2D point2, int n) throws Exception {
if (n == 0) {
drawLine(point1, point2);
return;
}
Point2D point1x = new Point2D(point1.x + (point2.x - point1.x) / 3, point1.y + (point2.y - point1.y) / 3);
Point2D point2x = new Point2D(point1.x + 2 * (point2.x - point1.x) / 3, point1.y + 2 * (point2.y - point1.y) / 3);
Point2D point3 = calculateRotatedPoint(point1x, Math.toRadians(120), point1);
drawSnowEdge(point1, point1x, n - 1);
drawSnowEdge(point1x, point3, n - 1);
drawSnowEdge(point3, point2x, n - 1);
drawSnowEdge(point2x, point2, n - 1);
}
private void drawSnowSymbol(int size, int numofedgle) throws Exception {
Point2D centerPoint = new Point2D(mapWidth / 2, mapWidth / 2);
Point2D[] points = new Point2D[numofedgle];
for (int i = 0; i < numofedgle; i++) {
points[i] = calculatePoint(centerPoint, Math.toRadians(90 + 360. / numofedgle * i), size);
}
for (int i = 0; i < numofedgle; i++) {
drawSnowEdge(points[i], points[(i + 1) % numofedgle], 3);
}
}
private void drawSpiral(int size, double deltaD, double deltaAngle) throws Exception {
Point2D centerPoint = new Point2D(mapWidth / 2, mapWidth / 2);
double d = 0;
double angle = 0;
while (d <= size) {
d += deltaD;
angle += Math.toRadians(deltaAngle);
try {
drawPoint(centerPoint.x + d * Math.cos(angle), centerPoint.y + d * Math.sin(angle));
} catch (Exception e) {
}
}
}
public static void main(String[] args) throws Exception {
Simple2DConsoleDrawer drawUtil = new Simple2DConsoleDrawer(200);
drawUtil.clearMap();
drawUtil.drawStar(80);
drawUtil.printMapToStdOut();
drawUtil.clearMap();
drawUtil.drawSnowSymbol(80, 3);
drawUtil.printMapToStdOut();
drawUtil.clearMap();
drawUtil.drawSpiral(200, 0.05, 0.5);
drawUtil.printMapToStdOut();
}
}