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.
Related
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;
}
I'm making a 2D topdown view shooter game with Java Swing. I want to calculate what angle the mouse pointer is compared to the center of the screen so some of my Sprites can look toward the pointer and so that I can create projectiles described by an angle and a speed. Additionally If the pointer is straight above the middle of the screen, I want my angle to be 0°, if straight to its right, 90°, if straight below 180°, and straight left 270°.
I have made a function to calculate this:
public static float calculateMouseToPlayerAngle(float x, float y){
float mouseX = (float) MouseInfo.getPointerInfo().getLocation().getX();
float mouseY = (float)MouseInfo.getPointerInfo().getLocation().getY();
float hypotenuse = (float) Point2D.distance(mouseX, mouseY, x, y);
return (float)(Math.acos(Math.abs(mouseY-y)/hypotenuse)*(180/Math.PI));
}
The idea behind it is that I calculate the length of the hypotenuse then the length of the side opposite of the angle in question. The fraction of the 2 should be a cos of my angle, so taking that result's arc cos then multiplying that by 180/Pi should give me the angle in degrees. This does work for above and to the right, but straight below returns 0 and straight left returns 90. That means that I currently have 2 problems where the domain of my output is only [0,90] instead of [0,360) and that it's mirrored through the y (height) axis. Where did I screw up?
You can do it like this.
For a window size of 500x500, top left being at point 0,0 and bottom right being at 500,500.
The tangent is the change in Y over the change in X of two points. Also known as the slope it is the ratio of the sin to cos of a specific angle. To find that angle, the arctan (Math.atan or Math.atan2) can be used. The second method takes two arguments and is used below.
BiFunction<Point2D, Point2D, Double> angle = (c,
m) -> (Math.toDegrees(Math.atan2(c.getY() - m.getY(),
c.getX() - m.getX())) + 270)%360;
BiFunction<Point2D, Point2D, Double> distance = (c,
m) -> Math.hypot(c.getY() - m.getY(),
c.getX() - m.getX());
int screenWidth = 500;
int screenHeight = 500;
int ctrY = screenHeight/2;
int ctrX = screenWidth/2;
Point2D center = new Point2D.Double(ctrX,ctrY );
Point2D mouse = new Point2D.Double(ctrX, ctrY-100);
double straightAbove = angle.apply(center, mouse);
System.out.println("StraightAbove: " + straightAbove);
mouse = new Point2D.Double(ctrX+100, ctrY);
double straightRight = angle.apply(center, mouse);
System.out.println("StraightRight: " + straightRight);
mouse = new Point2D.Double(ctrX, ctrY+100);
double straightBelow = angle.apply(center, mouse);
System.out.println("StraightBelow: " + straightBelow);
mouse = new Point2D.Double(ctrX-100, ctrY);
double straightLeft = angle.apply(center, mouse);
System.out.println("Straightleft: " + straightLeft);
prints
StraightAbove: 0.0
StraightRight: 90.0
StraightBelow: 180.0
Straightleft: 270.0
I converted the radian output from Math.atan2 to degrees. For your application it may be more convenient to leave them in radians.
Here is a similar Function to find the distance using Math.hypot
BiFunction<Point2D, Point2D, Double> distance = (c,m) ->
Math.hypot(c.getY() - m.getY(),
c.getX() - m.getX());
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.
I'm trying to draw an arc based on two given points and a given height describing a circle segment. To acomplish this I would use the following method from java.awt.Graphics.
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
First I observe that the x, y, width and height values describes a rectangle containing the circle.
The center of the arc is the center of the rectangle whose origin is (x, y) and whose size is specified by the width and height arguments. (http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html)
So first I start by calculating the x,y,width and height values. The picture below describes how I would do this.
The first picture shows what values I've already got. The arc in the first picture is exactly what I'm trying to draw. In picture number two I calculate the lenght of a line between the two points. My code to perform this step would look like this:
int dx = p1.x- p2.x;
int dy = p1.y - p2.y;
double len = Math.sqrt(Math.pow((double)dx, 2) + Math.pow((double)dy, 2));
As shown in picture three I can now calculate the radius of the circle by using the following function.
radius = h/2 + len^2 / 8h
The first problem I encounter is to calculate the CenterPoint of the circle. This is partly where I need help.
If I was to calculate the Center Point I can then easily find the x, y, whith and height coordinates.
x = centerPoint.x - radius;
y = centerPoint.y - radius;
width = radius * 2;
height = radius * 2;
The last part is to calculate the startAngle and arcAngle based on the values we already calculated.
TL;DR I need help with calculating the angles and the center point.
Thanks in advance!
There's a well-known relationship (see here, for instance) between the chord half length, the height of the arc (also called the sagitta), and the radius. Let the chord length (the distance between p1 and p2 be l = 2 d, let the arc height be h, and let the radius be r. Then
r = (d 2 + h 2) / (2 h)
The center is on the perpendicular bisector of the chord, at a distance r - h from the chord, on the opposite side from the arc.1 You can then use standard inverse trig functions to get the start and end angles for the chord.
1 Note that it is not enough to know p1, p2, and h; you need some way of identifying which side of the chord has the center and which side has the arc.
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