[JAVA] Logic to draw a circle with ASCII art on the console

↓ 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

Logic to draw a circle with ASCII art on the console
Come out with a suffix on the method
Come out with a suffix on the method 2
[Rails] When transitioning to a page with link_to, move to the specified location on the page
Fizzbuzz with ASCII art.
Implemented a strong API for "I want to display ~~ on the screen" with simple CQRS
[Java] I tried to make a rock-paper-scissors game that beginners can run on the console.
How to reduce the load on the program even a little when combining characters with JAVA
Four-in-a-row with gravity that can be played on the console
Apache Geode-Easy way to execute logic on the server side
[Swift 5] Select a date with the IDate Picker on iOS14
A memo to build Jitsi Meet on Azure with docker-compose
Add a shadow to the Swift Button (and also the circle)
Draw a gradient with CAGradientLayer
Input to the Java console
Try to imitate the idea of a two-dimensional array with a one-dimensional array
I want to add a browsing function with ruby on rails
Connecting to a database with Java (Part 1) Maybe the basic method
Replace with a value according to the match with a Java regular expression
[Rails] How to put a crown mark on the ranking function
I tried to display the calendar on the Eclipse console using Java.
Steps to build a Ruby on Rails development environment with Vagrant
(Ruby on Rails6) Create a function to edit the posted content
A story that I was addicted to twice with the automatic startup setting of Tomcat 8 on CentOS 8
I want to download a file on the Internet using Ruby and save it locally (with caution)
Put a badge on the icon
Programming with ruby (on the way)
Draw a pie chart with Chart.js
How to interact with a server that does not crash the app
How to check before sending a message to the server with Spring Integration
I made an app to scribble with PencilKit on a PDF file
Draw a bar graph and a line graph at the same time with MPAndroidChart
Minimal steps to set up a Ruby environment with rbenv on Ubuntu 20.04
I can't build if I set the build destination to a simulator with XCode12!
How to build a Ruby on Rails development environment with Docker (Rails 6.x)
Hanashi stumbled a little on path trying to study Java with VScode
How to debug the processing in the Ruby on Rails model only on the console
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
Send a request to the backend after authenticating with Spring Cloud Gateway