Java calculating points of Angles in a non-right triangle - java

I am currently working on a project in which i need to draw a non-right triangle in the center of a JFrame using either, java.awt.Graphics's drawLine() or drawPolygon() methods. Both of these methods require the coordinates of all of the points to function. My problem is that instead of points, all i have are all of the angles and side lengths of the triangle. I've drawn up a nifty diagram of what I hope helps you visualize my problem:
(EDIT the position of C in this Senario is not fixed betwen a and b and may be anywhere below the axis on which AB rests)
as you can see from my picture, I need the coordantes of C based off the coordanes of A, is there any way to calculate this given the lengths of all sides and angles of the non-right triangle?
Bonus: How would i find an (x, y) value for A that would effectivly center the triangle in the middle of the JFrame?

If you know angle CAB, the coordinate of point C should be:
(x+b·sin(θ), y-b·cos(θ))
In Java, there is:
double Math.sin(double radians);
double Math.cos(double radians);
Keep in mind that the angle needs to be in radians. If your angles are in degrees, try:
double Math.sin(Math.toRadians(double degrees));
double Math.cos(Math.toRadians(double degrees));
Hope this helps.

Related

Get radius from a circle to screen corners

I followed an online tutorial, I did not understand how the professor managed to get the distance of a circle from the top left corner of the screen:
//calculate the distance from epicenter (of a circle) to the top left corner of the screen
double theta = atan(epicenter.dy/epicenter.dx);
double distanceToCorner = epicenter.dy / sin(theta);
I would like to know how to get the distance from all the other screen corners (and possibly have an explanation of what has been done).
Thank you
Assuming, that in android you can get screen width and height, you can simply count the distance at horizontal and vertical axis separately.
Getting the distances at those axes, you can use Pythagoras equation, like
dist = sqrt( dx^2 * dy^2 )
To make it more felxible, just make a function, that takes corner position as a parameter and make the dx and dy as a absolute difference of corner and epicenter location.
Going back to your question and atan(...), I don't quite understand the need of using this here, except if that's a project for the math class :)
I know this is not the answer but if i understand what you mean, then this image might be helpful.

Find center point in polygon includes point Java

I have a problem. I have an array tag that includes the outline of a polygon, each point has gps coordinates.
I would like to find the focus point is in my array.
How can I do that?
I would like to have a gps coordinates of a red point (just one no matter).
Edit:
I have a area, i want center my zoom in a map at the middle of this area. This area is represented by a polygon of point. I want the coordinates of this point.
Loop through your points and remember the smallest and greatest x, y coordinate. After that your x-coordinate is xcenter = (xmax-xmin)/2 and ycenter = (ymax-ymin)/2. That's the geometrical center.
If you want the 'Centroid of polygon' you can take the formula discussed here: https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon (it's a sumformula over the coordinates).

Finding nearest free position for a circle for any point [x,y] in a 2D space with circles

I am making a game in which the user player places circles on the screen. It is important that the circles never overlap, so I need to figure out the nearest possible free spot from the cursor. I have found circle packing algorithms, but they do not seem a fit for my problem. I have also solved a similar problem in the past for boxes (here), but with circles, I cannot seem to figure it out.
I figured out how I can find the nearest free position when it intersects with one circle, or even when two are involved. However, I cannot find a robust algorithm that can deal with complex cases that have any number of circles in any arrangement.
Precise description of problem:
I have a 2D space with any number of non-intersecting circles, all with identical radii (though that may not matter). I want to find a position for the next circle that will make it not intersect with any other circle, and which center [x,y] is nearest to a specified location [x,y].
Suggestions of any kind appreciated (references, approaches, or (Java) libraries).
p.s. Bonus points if the solution includes making sure the circle stays within a specific bounding box (i.e. display).
My final solution: (based on David Wallace's suggestions)
Calculate the minimal distance between the centers of two circles (in my case, all circles are the same size, so always 2*radius)
Make a list of all circles that are closer to the mouse position than the minimum distance
If 0 overlaps: all good!
If 1 overlap: move the new circle's center to the minimum distance from the compared circle's center, along the vector that runs from compared circle's center to mouse position
If 2 overlap: find out where the two overlapping circles intersect. Place the new circle on the intersection closest to the mouse position. If this position still overlaps with any circle, move to the other intersection. If that one doesn't work, leave the new circle were it is.
If 3 overlap: same as in 2 overlap, just take the two circles closest to the new circle.
Note that this does not work perfectly, but good enough in my case, where a user is dragging the new circle on the screen. It works in most cases and in those it doesn't, usually when there are many circles very close together, the new circle simply stays in the last position (which was valid). The user can then decide to drag it a fit further and be more precise in where he wants the new circle to go.
This isn't a complete answer, but you may be able to make it into one.
Suppose you've already placed circles of radii r1, r2, r3 ... rn with centres C1, C2, C3 ... Cn, and you're looking to place a new circle of radius rz, the new circle's centre will have to be outside all of a set of "enlarged" circles, centred at C1, C2, C3 ... Cn; with radii (r1+rz), (r2+rz), (r3+rz) ... (rn+rz). So if the cursor is at point P, then there are some cases to consider.
(1) If P is not in any of the enlarged circles, then the problem is solved.
(2) If P is in just one of the enlarged circles, then move outwards along a radius of that circle, until you either reach a point that's outside all of the enlarged circles, or until you reach another enlarged circle. The former case reduces to scenario (1); the latter reduces to scenario (2). Pick an arbitrary direction if P happens to be the centre of the circle.
(3) If P is in several of the circles, then find the directions from P to each centre of a circle that it's in. Find the pair of directions that have the widest interval between them, and bisect that angle, to work out which direction to head along. For example, if the directions to the centres of the circles are 30deg, 120deg and 330deg, then bisect the angle between 120deg and 330deg - then head in a direction of 225deg. Head in that direction until you reach the edge of a circle, then recalculate. Keep doing this until you get back to scenario (2).
The thing that I can't work out is what to do if you get stuck in scenario (3). Maybe only allow a certain number of steps, then exit. After all, it's possible that there's no suitable place to put the circle.
To calculate the distance between a point and a circle is with the center, considering your Circle class is like this one:
public class Circle{
int x;
int y;
int radius;
}
public interface CircleHelper{
public int distanceBetweenCircleAndPoint(Circle c, Point p);
public int distanceBetweenTwoCircles(Circle c1, Circle c2);
}
First of all, I would think about using Quadtrees and check if there is any quad without surrounding circles
The quadtree deep can be selected considering the radius of the circles.
so if you have a point in one of the quads, you would look to its surrounding quads to check if there is any circle there and move from the point in the direction of empty quads.
I hope you understand my approach
Here is a solution that will work for varying radiuses, and can be simplified if all radiuses are equal, as in your case. We first transform the problem slightly. Instead of fitting a circle among other circles, we extend the radiuses of all other circles by the radius of our circle to place, and instead try to place a point outside of these extended circles. This is equivalent to the original problem. We proceed as follows:
First a special case. If the point is outside of all circles, we have a trivial solution.
Find all the circles the point is inside. Calculate the closest point on their circumference (just move out from the original point along the radius).
Find all the intersection points between pairs of circles.
Combine the sets of points from steps 2 and 3, and filter these by finding the ones that are not covered by any other circle.
Pick the closest point from the remaining set. Done!
This seems to be O(n^3), so not terribly fast, but should be doable if your set is not too huge.

Random angles of a bouncing ball

I'm trying to make a ball bounce around a window. Depending on how far away the ball hits the wall and at what angle will determine its reflection. You can see in the pic that the black trajectory hits the opposite wall on the inner half... and the gray trajectory represents if it were to reflect and hit the other half... which would decrease the angle of reflection.
I'm not sure if I'm thinking about it correctly... I'm trying to put the coordinates in terms of degrees.
So given the pic... You would take those deltas, then get degrees...
degree = Math.atan2(opposite/adjacent) = (-4/-2)
My code
public class Calculate {
public Calculate() {
System.out.println(getCalc(7,5,4,0));
}
public double getCalc(int x1, int x2, int y1, int y2) {
double deltaX = Math.abs(x2-x1);
double deltaY = Math.abs(y2-y1);
double degrees = Math.toDegrees((java.lang.Math.atan2(deltaX, deltaY)));
return degrees;
}
}
Gives the output: 26.56505117707799
So now I know the ball would reflect off the wall at 26 degrees (since that's the angle of incidence). But I don't want the ball to necessarily reflect uniformly off each wall so it adds variability.
My questions:
Am I calculating the angle of the ball correctly?
How can I add variability to the bounce based on where it hits on the wall?
Once I have the angle in degrees, how can I translate that back to coordinates?
Thank you!
Am I calculating the angle of the ball correctly?
Your drawing is not to scale. The 26 degrees is measured from a line perpendicular to the wall.
How can I add variability to the bounce based on where it hits on the wall?
You already suggested a random angle. You can also adjust the angle of reflection based on the distance from the center of the wall.
Put your angle of reflection calculation into its own method. You can adjust the calculation until your calculations give you the "randomness" you're looking for.
Once I have the angle in degrees, how can I translate that back to coordinates?
Convert the degrees to radians, then calculate the SAS of the triangle. Just leave your angles in radians in the model, and convert to degrees in your display / diagnostic methods.
I think that the distance of the ball from the surface doesn't really have an effect on the angle. The angle of the ball before hitting the surface should be the same (mirror reflected) when it leaves the surface for it to be natural.
You can add some variability by thinking what happens to a rubber ball, since it changes a little on impact depending on the force etc., the reflection is not exactly the same every time. You could simply add or remove a degree or two randomly and see how it goes.
Once you have an angle, its once again down to trigonometry. You have an angle, and you know the hypotenuse (I presume depending on your frame-rate and ball speed the ball would have travelled a certain amount from the surface). So from that you need to get the adjacent and opposite lines of the triangle.
For example:
sin(angle) * hypothenuse = opposite (so Y offset from the surface).
cos(angle) * hypothenuse = adjacent (so X offset from the point of contact).
Just add or remove (depending on the direction) the adjacent and opposite values from the coordinates of the contact point.
If you want to make it seem a little random, you could model spin somewhat--it doesn't have to be too complicated.
If it was not spinning and hit a wall at a 45 degree angle, it would impart a spin to the ball. When it hit the next wall, the spin would added to the angle and the spin would be increased (or decreased) by the angle. I think the spin/angle combination would also effect the speed at which it came off the wall (Just visualizing real-life situations)
That would make it vary without it being truly random--but I don't know how it would actually look--you may have to apply other restrictions (I think that there must be a way to limit the max spin).
I bet there is a simple physics book around that could give enough to model this without going too deep into the math if you didn't just want to make up rules.

Finding angle from center point on circle [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Find angle of a point from center of circle
Imagine a circle, the center point is fixed, as is the point at the top of the circle. What i want is to give a third point anywhere around the circle (or outside the circle) and get the degrees from the center to top point line from 0-359. (I actually graphed out a nice picture illustrating but im new and cant post it)
To give some context, the circle is a little planet and I want do place a little building on the surface with the base of the building at a tangent. I need the rotation angle for my building bitmap.
edit: Thanks for the help, i'm still struggling with this one though. I wonder could it be relevant that I'm using android and the y0 coordinate is at the top? Is it the other way around on other platforms? would that affect the calculation?
Solution: Because I am in android and the y coords are counted from top to bottom I had to change a - witha +
degrees = Math.atan2(x - centerX, -y + centerY);
// and to make it count 0-360
if (degrees < 0) {degrees += 2 * Math.PI;}
Use Math.atan2() to get the angle in radians from east, and then rotate and convert as appropriate.
Note that atan2 is defined as atan2(y, x) NOT atan2(x, y), as you might expect.
Get the horizontal distance and the vertical difference between the center and the point, divide one by the other, and pass the result to the method Math.asin(double).
The result will be the angle in radians. When you need it in degree, you can use the method Math.toDegrees(double). Most APIs I know prefer radians, though.

Categories