JAVA draw regular polygon - java

I am looking for an algorithm to draw regular polygon like triangle, quadrangle, pentagon, hexagon etc.
I guess it`s basically dealing with the fact that all polygon points are located on the line of the circle.
What`s the algorithm to calculate those N points for Polygon object?
After drawing a regular polygon I need to draw another regular polygon based on the first one but rotated by K degrees.

Use sin and cos:
double theta = 2 * Math.PI / sides;
for (int i = 0; i < sides; ++i) {
double x = Math.cos(theta * i);
double y = Math.sin(theta * i);
// etc...
}
To rotate just add a constant offset to the angle, i.e. theta * i + offset.

The vertices of an N-vertex polygon are located at the angles
(2*Math.PI*K)/N
where K goes from 0 to N-1, inclusive. The vertical coordinate can be calculated as a sine of the angle times the radius of the circumcircle; the horizontal coordinate is calculated the same way, except you need to multiply the radius by the cosine of the angle.
In order to turn your polygon by X degrees, convert X to radians, and add the result to the angle in the formula, like this:
(2*Math.PI*K)/N + Xrad
Finally, since the origin of the screen is in one of the corners, only a portion of your polygon is going to be visible. To avoid this, add an offset equal to the position of the circumcircle's center to each coordinate that you calculate.

sin, cos, radius, 2*PI / number of sides and a loop

Related

Trying to draw polygons with JFrame

I want to code a program in java that utilises loops and JFrame to create various polygons around one another.
ie. Triangle, then Square, then Pentagon etc...
Refrence image of example
super.paintComponent(g);
int y = 0;
int z = 0;
g2D.setPaint(Color.CYAN);
Polygon p = new Polygon();
for (int x = 4; x < 10; x++) {
y = y + 50;
z = z + 100;
System.out.println("y = "+y);
System.out.println("z = " + z);
for (int i = 0; i < 10; i++) {
p.addPoint((int) (z + y * Math.cos(i * 2 * Math.PI / x)),
(int) (z + y * Math.sin(i * 2 * Math.PI / x)));
}
g2D.drawPolygon(p);
}
}
Output of Code
Any help would be much appreciated.
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay close attention to the Performing Custom Painting section.
This is a picture of what the OP is supposed to draw.
The only regular polygon in the picture is the square. At least, I think it's a square.
The triangle is an isosceles triangle.
I'm not sure how you would define the pentagon. The five sides are not equal in length. The side two segments are shorter than the bottom segment. The top two segments appear to be longer than the bottom segment.
You can't use the center point and angle of rotation math to create the polygons. The triangle is not an equilateral triangle.
You have to create this by calculating line segments. I'm assuming that the three polygons share the same base. Calculate one line segment at a time and test your code. You're going to run hundreds of tests before you're done.
I'd start by calculating the square first. A square is made up of four equal length line segments. To start, I'd take 1/2 of the width of the drawing area to be the length of the line segment. The first two X values are at the 1/4 and 3/4 points. The Y value can be 20 pixels off the bottom.
Now that you've drawn one line segment, calculate the line segments for the square. Draw the square.
Find the midpoint of the top square line segment. calculate the triangle line segments. Draw the triangle.
For the pentagon, the side line segments are shorter than the line segments of the square. Each angle of a regular pentagon is 108 degrees from the previous line segment. This polygon has slightly different angles at each point.
You'll have to experiment with the pentagon line segment lengths until the top two segments just intersect the square line segments. You could probably do the math, but I suspect it would be easier to just keep guessing until you get an acceptable drawing.
Edited to add:
I created the following GUI.
Calculating the pentagon line segments took the most time.
The side line segments are 85% of the line length of the bottom line segment. I used a 105 degree angle to calculate the end points of the side line segments.
I used a slope formula to calculate the y point of the top line segments. I'd already calculated the start point and the intersect point to draw the pentagon side line segments and the square, respectively. This calculation took most of my debugging time.
Edited to add:
I don't want to just give you the complete code. Part of learning is struggling with the code and learning how to solve problems as they come up. As I said, you should be writing a little bit of code at a time and testing each little bit of code to see what it does.
Here are two methods I wrote to calculate the four additional pentagon line segments. The Point class is java.awt.Point.
private Point calculateSideSegment(Point start, int radius, int angle) {
double theta = Math.toRadians(angle);
int x = (int) Math.round(Math.cos(theta) * radius) + start.x;
int y = (int) Math.round(Math.sin(theta) * radius) + start.y;
return new Point(x, y);
}
private int calculateTopSegment(Point start, Point intersect, int x) {
int yDiff = start.y - intersect.y;
int xDiff1 = start.x - intersect.x;
int xDiff2 = start.x - x;
double slope = (double) yDiff / xDiff1;
double y = Math.round(slope * xDiff2);
return start.y - (int) y;
}

Drawing Spiral Using Java in Processing

I have a Java program written in Processing I made that draws a spiral in processing but I am not sure how some of the lines of code work. I wrote them based on a tutorial. I added comments in capital letters to the lines I do not understand. The comments in lowercase are lines that I do understand. If you understand how those lines work, please explain in very simple terms! Thank you so much.
void setup()
{
size(500,500);
frameRate(15);
}
void draw()
{
background(0); //fills background with black
noStroke(); //gets rid of stroke
int circlenumber = 999;// determines how many circles will be drawn
float radius = 5; //radius of each small circle
float area = (radius) * (radius) * PI; //area of each small circle
float total = 0; //total areas of circles already drawn
float offset = frameCount * 0.01; //HOW DOES IT WORK & WHAT DOES IT DO
for (int i = 1; i <= circlenumber; ++i) { // loops through all of the circles making up the pattern
float angle = i*19 + offset; //HOW DOES IT WORK & WHAT DOES IT DO
total += area; // adds up the areas of all the small circles that have already been drawn
float amplitude = sqrt( total / PI ); //amplitude of trigonometric spiral
float x = width/2 + cos(angle) * amplitude;//HOW DOES IT WORK & WHAT DOES IT DO
float hue = i;//determines circle color based on circle number
fill(hue, 44, 255);//fills circle with that color
ellipse(x, 1*i, radius*2, radius*2); //draws circle
}
}
Essentially what this is doing is doing a vertical cosine curve with a changing amplitude. Here is a link to a similar thing to what the program is doing. https://www.desmos.com/calculator/p9lwmvknkh
Here is an explanation of this different parts in order. I'm gonna reference some of the variables from the link I provided:
float offset = frameCount * 0.01
What this is doing is determining how quickly the cosine curve is animating. It is the "a" value from desmos. To have the program run, each ellipse must change its angle in the cosine function just a little bit each frame so that it moves. frameCount is a variable that stores the current amount of frames that the animation/sketch has run for, and it goes up every frame, similar to the a-value being animated.
for (int i = 1; i <= circlenumber; ++i) {
float angle = i*19 + offset;
This here is responsible for determining how far from the top the current ellipse should be, modified by a stretching factor. It's increasing each time so that each ellipse is slightly further along in the cosine curve. This is equivalent to the 5(y+a) from desmos. The y-value is the i as it is the dependent variable. That is the case because for each ellipse we need to determine how far it is from the top and then how far it is from the centre. The offset is the a-value because of the reasons discussed above.
float x = width/2 + cos(angle) * amplitude
This calculates how far the ellipse is from the centre of the screen (x-centre, y value is determined for each ellipse by which ellipse it is). The width/2 is simply moving all of the ellipses around the centre line. If you notice on Desmos, the center line is y-axis. Since in Processing, if something goes off screen (either below 0 or above width), we don't actually see it, the tutorial said to offset it so the whole thing shows. The cos(angle)*amplitude is essentially the whole function on Desmos. cos(angle) is the cosine part, while amplitude is the stuff before that. What this can be treated as is essentially just a scaled version of the dependent variable. On desmos, what I'm doing is sqrt(-y+4) while the tutorial essentially did sqrt(25*i). Every frame, the total (area) is reset to 0. Every time we draw a circle, we increase it by the pi * r^2 (area of circle). That is where the dependent variable (i) comes in. If you notice, they write float amplitude = sqrt( total / PI ); so the pi from the area is cancelled out.
One thing to keep in mind is that the circles aren't actually moving down, it's all an illusion. To demonstrate this, here is some modified code that will draw lines. If you track a circle along the line, you'll notice that it doesn't actually move down.
void setup()
{
size(500,500);
frameRate(15);
}
void draw()
{
background(0); //fills background with black
noStroke(); //gets rid of stroke
int circlenumber = 999;// determines how many circles will be drawn
float radius = 5; //radius of each small circle
float area = (radius) * (radius) * PI; //area of each small circle
float total = 0; //total areas of circles already drawn
float offset = frameCount * 0.01; //HOW DOES IT WORK & WHAT DOES IT DO
for (int i = 1; i <= circlenumber; ++i) { // loops through all of the circles making up the pattern
float angle = i*19 + offset; //HOW DOES IT WORK & WHAT DOES IT DO
total += area; // adds up the areas of all the small circles that have already been drawn
float amplitude = sqrt( total / PI ); //amplitude of trigonometric spiral
float x = width/2 + cos(angle) * amplitude;//HOW DOES IT WORK & WHAT DOES IT DO
float hue = i;//determines circle color based on circle number
fill(hue, 44, 255);//fills circle with that color
stroke(hue,44,255);
if(i%30 == 0)
line(0,i,width,i);
ellipse(x, i, radius*2, radius*2); //draws circle
}
}
Hopefully this helps clarify some of the issues with understanding.

Java - How to check of a point is inside a sliceof a circle

I have a circle drawn, and I want to make it so I can have more slices than four. I can easily do four quadrants because I just check if the mouse in in the circle and inside a box.
This is how I am checking if the point is in the circle.
if( Math.sqrt((xx-x)*(xx-x) + (yy-y)*(yy-y)) <= radius)
{
return true;
}
else
{
return false;
}
How can I modify this if the circle is divided into more than 4 regions?
For radial slices (circular sectors), you have a couple of alternatives:
Use Math.atan2 to calculate the 4-quadrant angle of the line from the circle center to the point. Compare to the slice angles to determine the slice index.
For a particular slice, you can test which side of each slice edge the point falls. Classify the point accordingly. This is more complicated to calculate but probably faster (for a single slice) than calling Math.atan2.
The following sample code calculates the slice index for a particular point:
int sliceIndex(double xx, double yy, double x, double y, int nSlices) {
double angle = Math.atan2(yy - y, xx - x);
double sliceAngle = 2.0 * Math.PI / nSlices;
return (int) (angle / sliceAngle);
}
The above code makes the following assumptions:
slices are all the same (angular) width
slices are indexed counter-clockwise
slice 0 starts at the +x axis
slices own their right edge but not their left edge
You can adjust the calculations if these assumptions do not apply. (For instance, you can subtract the start angle from angle to eliminate assumption 3.)
First we can check that the point is within the circle as you did. But I woudln't combine this with a check for which quadrant (is that why you have radius/2 ?)
if( (xx-x)*(xx-x) + (yy-y)*(yy-y) > radius*radius)
return false;
Now we can look to see which region the point is in by using the atan2 function. atan2 is like Arctan except the Arctangent function always returns a value between -pi/2 and pi/2 (-90 and +90 degrees). We need the actual angle in polar coordinate fashion. Now assuming that (x,y) is the center of your circle and we are interested in the location of the point (xx,yy) we have
double theta = Math.atan2(yy-y,xx-x);
//theta is now in the range -Math.PI to Math.PI
if(theta<0)
theta = Math.PI - theta;
//Now theta is in the range [0, 2*pi]
//Use this value to determine which slice of the circle the point resides in.
//For example:
int numSlices = 8;
int whichSlice = 0;
double sliceSize = Math.PI*2 / numSlices;
double sliceStart;
for(int i=1; i<=numSlices; i++) {
sliceStart = i*sliceSize;
if(theta < sliceStart) {
whichSlice = i;
break;
}
}
//whichSlice should now be a number from 1 to 8 representing which part of the circle
// the point is in, where the slices are numbered 1 to numSlices starting with
// the right middle (positive x-axis if the center is (0,0).
It is more a trig problem Try something like this.
int numberOfSlices=8;
double angleInDegrees=(Math.toDegrees(Math.atan2(xx-x ,yy-y)));
long slice= Math.round(( numberOfSlices*angleInDegrees )/360 );

Put points round into circular arc used in java

I have me math question: I have known a circle center and radius, and have some uncertain number of points called N, my question is how to put the points on the circular arc, I cannot like put the points around the whole circumference, other as this link: http://i.6.cn/cvbnm/2c/93/b8/05543abdd33b198146d473a43e1049e6.png
in this link, you can read point is circle center, other color is some points, you can see these points around the arc.
Edit - in short: I have known a circle center and radius, so I want to generate some point around the circle center
I am not sure, but I checked this with simple Swing JComponent and seems ok.
Point center = new Point(100, 100); // circle center
int n = 5; // N
int r = 20; // radius
for (int i = 0; i < n; i++)
{
double fi = 2*Math.PI*i/n;
double x = r*Math.sin(fi + Math.PI) + center.getX();
double y = r*Math.cos(fi + Math.PI) + center.getY();
//g2.draw(new Line2D.Double(x, y, x, y));
}
It's not entirely clear what you're trying to accomplish here. The general idea of most of it is fairly simple though. There are 2*Pi radians in a circle, so once you've decided what part of a circle you want to arrange your points over, you multiply that percentage by 2*pi, and divide that result by the number of points to get the angle (in radians) between the points.
To get from angular distances to positions, you take the cosine and sine of the angle, and multiply each by the radius of the circle to get the x and y coordinate of the point relative to the center of the circle. For this purpose, an angle of 0 radians goes directly to the right from the center, and angles progress counter-clockwise from there.

Draw a line at a specific angle in Java

Let's say I have an (x,y) that is always the same for the start point of a line and an (x,y) that changes for the end point of that same line. The line is also always 40px long. At the start of the program the line originates in a vertical orientation (lets call it 0 degrees). Based on a user input I need the line to be redrawn a specific number of degrees from its origin by changing only the end (x,y).
SOME MORE FOOD FOR THOUGHT IF YOU NEED IT:
I'm in a rut trying to calculate this and make it work in Java. I can make the math work to calculate the point based on the arc length of a circle segment, but I don't know how to make Java do it.
I think it would work easier based off a triangle angles since I will always know the length of two sides of a triangle (one side formed by the 40px long line and the other side formed by the start point of that line and the border of the JPanel) and the angle those two lines form. Still, my brain is mush from trying to figure it out. Any help would be much appreciated.
UPDATE:
#casablanca got me on the right track. I brushed up on my trig functions and here is how I made it work.
First off, I didn't realize that 90 degrees was straight up, but once I did realize that I made my solution reflect that fact. I was drawing my line starting at the bottom center of the frame going out. Since the opposite side of the triangle is on the right side of the screen when the angle given by my user is less than 90 degrees and is on the left side of the screen when the angle given by my user is greater than 90 degrees I had to adjust the formula to account for that fact, thus I have four methods, one for the x coordinate on the left side of the screen (when the user given angle is greater than 90 degrees), one for the y coordinate on the left side of the screen (when the user given angle is greater than 90 degrees) and the same thing for the right side of the screen when the user given angle is less than 90 degrees. The int length in all methods is the length of the hypotenuse. Thanks again for your help #casablanca!
public double leftSideX(double angle, int length){
double x = frameWidth/2 - (length * Math.cos(Math.toRadians(90-(Math.toDegrees(angle)-90))));
return x;
}
public double leftSideY(double angle, int length){
double y = frameHeight - (length * Math.sin(Math.toRadians(90-(Math.toDegrees(angle)-90))));
return y;
}
public double rightSideX(double angle, int length){
double x = frameWidth/2 + (length * Math.cos(angle));
return x;
}
public double rightSideY(double angle, int length){
double y = frameHeight - (length * Math.sin(angle));
return y;
}
Is this what you're looking for?
startX = x;
startY = y;
endX = x + 40 * Math.sin(angle);
endY = y + 40 * Math.cos(angle);
And draw a line from (startX, startY) to (endX, endY) in whatever API you're using.
Also note that angle is in radians. If you had it in degrees, you need to convert it first:
angle = angle * Math.PI / 180;

Categories

Resources