↓ Draw something like this (Qiita makes an ellipse and it's hard to see ...)
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●○○○○○○○○○○●●●●●●●●●●●
●●●●●●●●○○○○○○○○○○○○○○●●●●●●●●●
●●●●●●○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●○○○○○○○○○○○○○○○○○○○○●●●●●●
●●●●○○○○○○○○○○○○○○○○○○○○○○●●●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●○○○○○○○○○○○○○○○○○○○○○○○○○○○○●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●●○○○○○○○○○○○○○○○○○○○○○○○○○○●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●●○○○○○○○○○○○○○○○○○○○○○○○○●●●●
●●●●○○○○○○○○○○○○○○○○○○○○○○●●●●●
●●●●●○○○○○○○○○○○○○○○○○○○○●●●●●●
●●●●●●○○○○○○○○○○○○○○○○○○●●●●●●●
●●●●●●●●○○○○○○○○○○○○○○●●●●●●●●●
●●●●●●●●●●○○○○○○○○○○●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
The solution by the three-square theorem and I implemented it by the solution method by trigonometric function + 2-minute search.
It seems that digital differential analysis can be drawn only by addition / subtraction and shift. Drawing a circle (1) Algorithm for drawing an arc
Of these, I think the three-square theorem is probably the easiest to understand.
import static java.lang.System.out;
import java.util.stream.IntStream;
public abstract class Draw {
//Entry point
public static void main(String... args) {
Integer size = 31;//Size to draw
//Solving by the three-square theorem
new DrawCircle(size) {
@Override
Integer threshold(Integer r, Integer x) {
Integer threshold = Double.valueOf(Math.sqrt(r * r - x * x)).intValue();
return threshold;
}
}.drow();
out.println();
//Trigonometric function + 2-minute search solution
new DrawCircle(size) {
Integer threshold(Integer r, Integer x) {
return threshold(r, x, new Double(45), new Double(45/2));
}
Integer threshold(Integer r, Integer x, Double angle, Double incAngle) {
Integer _x = (int)Math.round(Double.valueOf(r * Math.cos(Math.toRadians(angle))));
double nextIncAngle = incAngle/2 > 1 ? incAngle/2 : 1;
if( _x.intValue() > x ) {
return threshold(r, x, angle + incAngle, nextIncAngle);
}else if( _x.intValue() < x ) {
double _angle = angle - incAngle;
if( _angle < 0 ) {//I haven't investigated it well, but when x reaches the maximum value, it becomes an infinite loop, so judge by angle and guard
return 0;
}else {
return threshold(r, x, _angle, nextIncAngle);
}
}
return Double.valueOf(r * Math.sin(Math.toRadians(angle))).intValue();
}
}.drow();
}
//Circle drawing class
abstract static class DrawCircle extends Draw{
DrawCircle(Integer size) {
super(size);
}
@Override
Boolean algorithm(Integer x, Integer y) {
Integer r = size / 2;
x = fixPostion(r, x);
y = fixPostion(r, y);
Integer threshold = threshold(r, x);
return y > threshold;
};
/**
*Get the threshold of whether it is inside or outside the circle in the vertical direction
* @param r radius
* @param x horizontal scale
* @return Vertical threshold
*/
abstract Integer threshold(Integer r, Integer x);
/**
*Calculate the position of the circle to be calculated from the coordinates(It's a subtle explanation ...)。
* @param r radius
* @param x coordinates
* @return
*/
Integer fixPostion(Integer r, Integer x){
if(r < x) {
x -= r;//Right half calculation
}else {
x = r - x + 1;//15 because 1 starts->1, 14->2... 1->Convert to 15
}
return x;
}
}
//Contents of Draw class
Integer size;
Draw(Integer size) {
this.size = size;
}
abstract Boolean algorithm(Integer x, Integer y);
void drow() {
IntStream.rangeClosed(1, size).forEach(y -> {
IntStream.rangeClosed(1, size).forEach(x -> {
out.print(algorithm(x, y) ? "●" : "○");
});
out.println();
});
}
}
Recommended Posts