Search for a location inside of a area radius - java

I am building a minecraft plugin.
Basically my world limit is set by radius off the spawn location, instead of having 4 corners to determine the limited region of the world.
So my world limit is a round radius for example of distance of 1000 blocks.
Now I want to place a small 50x50 round area of blocks inside of that area of 1000 blocks radius, so I need to find a random coordinate which will be the center point of the round area I am going to make.
Question
How to get a random coordinate in a radius based area, is there an equation for that? I can't just do spawnX + rand(-1000,1000) and for spawnZ, because the area is round.
How can I make sure that the whole round area I want to put in will fit in the big radius area?

To pick a random spot in a circle would be a random angle and a random number within the radius:
random_angle = random(2π)
random_dist = random(radius)
random_x = cos(random_angle) * random_dist
random_y = sin(random_angle) * random_dist
To ensure a round area fits into another round area you calculate the distance from the middle for the small round + its radius and as long as that's equal to or less than the bigger round then it fits in.
To find the distance is a² + b² = c². So subsitute that for x and y to get:
distance = √(x_diff² + y_diff²)
This all assumes your co-ords start at (0, 0) in the middle of the map circle. If not you can calculate that by adding half the width and height to all co-ords.

If you want each point of your circle to have an equal chance of being selected, you can generate a set of polar coordinates instead, then convert it to cartesian coordinates.
Generate these random numbers:
r: between 0 and 1000
theta: between 0 and 2π
Assuming the centre of the circle is (0,0), the cartesian coordinates are:
x = r * cos(theta)
y = r * sin(theta)
To ensure that the smaller circle with radius 50 is inside the big circle, just limit r to be between 0 and 950 instead.

I'm not sure if I understand your problem correctly, but I think you can use circle formula for your coordinates. In a circle, we always have:
X^2+Y^2=R^2
so if you select x = spawnX + rand(-1000,1000), then you can calculate possible y range with aforementioned formula.

Related

draw a circle in three dimensional coordiantes [duplicate]

This question already exists:
circle in three dimensional coordiantes [closed]
Closed 1 year ago.
I want to draw a circle in three dimensional coordiantes, i'm given a vector, the angle where vector's intersects with the circle is 90 degrees, the intersection point is the centre of the circle. The radius can be parametrized. EDIT: I am programming a server plugin for minecraft. At this point I have made a sword that can be thrown. I want to add some decor. I want that after the sword there was a trace in the form of a circle. But I don't understand how to draw a circle in 3D coordinates so that the angle of intersection of the sword throw vector with the center of the circle is 90 degrees. The radius can be arbitrary, and the vector can enter the center of the circle. I thought I could just rotate the throw vector on 3 axes and get a circle, but nothing worked. I need an equation with which I can draw a given circle.
You have center C, normal vector N, radius R. Seems you want to get points at the circumference.
At first get some base vector in the circle plane.
Possible way:
Reveal normal component with the largest magnitude and with the second magnitude. For example, abs(N.X) is the largest, abs(N.Z) has the second magnitude, and abs(N.Y) is the smallest. Make the smallest component zero, exchange two larger ones, and negate the largest. For this example base vector will be:
A = (N.Z, 0, -N.X)
It is perpendicular to normal, hence lies in the circle plane.
Then get the next basis vector using vector product (B will be perpendicular both to A and to N, it lies in the plane too)
B = N x A
Now normalize vectors A and B (make them unit length)
A = A / len(A)
B = B / len(B)
and you can get any point at the circumeference with parametric equation where t changes in the range 0..2*Pi
P(t) = C + R * A * Cos(t) + R * B * Sin(t)
or in components:
P.X = C.X + R * A.X * Cos(t) + R * B.X * Sin(t)
and so on

Computer Graphics: Rotating a polygon

Purpose
I'm implementing a polygon rotation with Java AWT.
I'm already able to draw polygons on the screen, and I'd like to apply a rotation matrix manually upon my polygons coordinates (rotation is done around the lookAt point of the user).
What I've already done
In order to rotate the world, the user first clicks on the screen and then drags the mouse around to perform the rotation.
Let's note the first click point as S, the following point from the drag event as L, and the center of the screen as C.
In order to calculate the rotation angle, when first clicking the screen, I keep a vector from C to S: C-S.
Then, when a drag event occurs, I calculate the vector from C to L: C-L.
I then calculate the angle in radians between C-S to C-L, and that's what I apply on my world.
This works well, and the polygon is indeed rotation around the lookAt point.
My problem
The problem occurs when the user finishes a rotation of PI, and then the polygon is rotating backward.
e.g. When the user starts rotating, the angle starts from 0.1.... 0.2... 1.. 2.. 3.. and in value ~3.1 (I assume PI), the values are starting to go down: 3... 2.. 1.. until 0, and vice versa.
This makes sense since the radians range is [0, PI].
I assume the base vector C-S lies on the right side of X axis, and when the rotation goes down below the X axis the polygon is rotating backwards.
However, I have no idea how to keep the polygon rotating in the same direction all the time (when the user performs a full rotation around the polygon).
Edit
Angle function is:
public final double angle(Vector2D v1)
{
double vDot = this.dot(v1) / ( this.length()*v1.length() );
if( vDot < -1.0) vDot = -1.0;
if( vDot > 1.0) vDot = 1.0;
return ((double) (Math.acos( vDot )));
}
This is a problem of the arcus cosine, acos(cos(x)) is a periodic hat function moving up and down in the range of 0 to pi.
In higher dimensions that can not be avoided, as there is no preferred frame of reference, so there is no way to say that phi should really be -phi. In 2 dimensions there is a prefered orientation of the plane so that one can say what is the first and what the second vector and define a unique angle in positive orientation. Rotate the situation so that the first vector comes to lay on the positive real half axis to get the angle and correct quadrant from the coordinates of the rotated second vector.
Easiest to reconstruct is the complex picture, to compute the angle from a=a.x+i*a.y to b=b.x+i*b.y rotate b back by multiplying with the conjugate of a to get an angle from the zero angle resp. the positive real axis,
arg((a.x-i*a.y)*(b.x+i*b.y))
=arg((a.x*b.x+a.y*b.y)+i*(a.x*b.y-a.y*b.x))
=atan2( a.x*b.y-a.y*b.x , a.x*b.x+a.y*b.y )
Note that screen coordinates use the opposite orientation to the cartesian/complex plane, thus change atan2(y,x) to atan2(-y,x) to get an angle in the usual direction.
public Point rotate(Point original, Point vertex, double angle){
Point translated = new Point(original.x - vertex.x, original.y - vertex.y);
int x = (int)Math.round(translated.x * Math.cos(angle) - translated.y * Math.sin(angle));
int y = (int)Math.round(translated.x * Math.sin(angle) + translated.y * Math.cos(angle));
return new Point(vertex.x+x,vertex.y+y);
}
This is a simple rotation method that you can use to rotate a point around a given vertex.

How to check if lng/lat bounding box intersects with another?

Assume I have several bounding boxes with 4 coordinates pair (long/lat only) each representing the 4 corners of a square box. How can I check if 2 of those boxes intersects?
I know I could use java.awt.Rectangle to check if 2 rectangles intersects, but the problem is it is calculated using X/Y/Width/Height instead of coordinates.
Can someone please give me some directions on how can I do this calculations?
Thanks.
EDIT
What I am trying to accomplish is the same represented by this library.
Basically it calculates a square bounding box around a given point and check if the (imaginary) squares intersects with each other, like in this image:
(source: google.com)
So far I've been able to calculate the corners for each marker and now I need to somehow check if they intersect with each other. How can I do this intersection calculation?
EDIT 2
This is how I am calculating the corners:
private static double getLatitude(double distance, double lat, double angle) {
return toDegrees(asin(sin(toRadians(lat)) * cos(distance / RADIUS) + cos(toRadians(lat)) * sin(distance / RADIUS) * cos(toRadians(angle))));
}
private static double getLongitude(double distance, double lat, double lng, double angle) {
double newLat = getLatitude(distance, lat, angle);
return toDegrees(toRadians(lng) + atan2(sin(toRadians(angle)) * sin(distance / RADIUS) * cos(toRadians(lat)), cos(distance / RADIUS) - sin(toRadians(lat)) * sin(toRadians(newLat))));
}
Where RADIUS = 6378.1 and angle = 45/135/225/315 (top right, bottom right, bottom left and top left).
Example output
I'm assuming that in your "lat/long bounding box' each side follows the lines of constant longitude and latitude - in other words that the top side follows the line of constant latitude, and the left side the line of constant longitude.
While this is not actually a rectangle in real life, it can actually be treated as one for our purposes. Mathematically you can think of this as transforming the bounding box into a "lat/long' space, where the shape is in fact a rectangle. If that doesn't make sense you may have to take my word for it. In any case it is possible to show that the curved shapes in real space intersect if and only if the rectangles intersect in curved space.
The short version of this is: if you do a standard test for intersection of rectangles (using the Java Rectangle class code, and using latitude and longitude as the rectangle bounds) you will get the right result.
EXAMPLE
You have two areas, defined as:
The area between 50 and 52 degrees N and 75 and 77 degrees E
The area between 51 and 53 degrees N and 76 and 79 degrees E
You can correctly test for their intersection by doing:
Rectangle r1 = new Rectangle(75,50,2,2);
Rectangle r2 = new Rectangle(76,51,2,3);
boolean intersects = r1.insersects(r2);
It doesn't matter that the rectangles are not rectangular in Euclidean space.
P.S. This will not work if one of your rectangles actually contains either the north or south pole. In that case you will need to split each rectangle into two, one on each side of the pole. You need to normalize everything to +/- 90 latitude and +/- 180 longitude. You will need to do something clever if one or more of the rectangles overlaps the +/-180 longitude line.

Move an object based on acceleration

i want to use an acceleration algorithm to change the speed of a supposed aicraft to move it in a 2D environment. In example:
positionX = positionX + (speed based on acceleration);
positionY = positionY + (speed based on acceleration);
My problem is that if i do it like that the result, assuming the speed is 50, will be position += 50, which is entirely wrong since i don't want to use speed as the number of X it will move on the axis. I want the speed to be some sort of basis for the axis numbers.
In example, if lets say speed is 50 and 50 speed means 3 X per movement then that means
positionX + speed = positionX+3;
I want to create that in code along with an acceleration method that will increase the speed by a percentage.
So my question is how to make speed as a reference point kind of thing.
Keep it simple. The physics aren't difficult. The "math" is no more difficult than multiplying and adding.
You want to deal with changes in velocity and position over increments of time.
Position, velocity, and acceleration are vector quantities. In your 2D world, that means that each one has a component in the x- and y-directions.
So if you increment your time:
t1 = t0 + dt
Your position will change like this if the velocity is constant over that time increment dt:
(ux1, uy1) = (ux0, uy0) + (vx0*dt, vy0*dt)
The velocity will change like this if the acceleration is constant over that time increment dt:
(vx1, vy1) = (vx0, vy0) + (ax0*dt, ay0*dt)
Update your accelerations if there are forces involved using Newton's law:
(ax0, ay0) = (fx0/m, fy0/m)
where m is the mass of the body.
Update the positions, velocities, and accelerations at the end of the time step and repeat.
This assumes that using the values for acceleration and velocity at the start of the step is accurate enough. This will limit you to relatively smaller time steps. (It's called "explicit integration".)
Here's an example. You have a cannon at (x, y) = (0, 0) with a cannonball of mass 20 lbm inside it. The cannon is inclined up from the horizontal at 30 degrees. We'll neglect air resistance, so there's no force in the x-direction acting on the cannonball. Only gravity (-32.2 ft/sec^2) will act in the y-direction.
When the cannon goes off, it'll launch the cannonball with an initial speed of 40 ft/sec. The (vx, vy) components are (40*cos(30 degrees), 40*sin(30 degrees)) = (34.64 ft/sec, 20 ft/sec)
So if you plug into our equations for a time step of 0.1 second:
(ax0, ay0) = (0, -32.2 ft/sec^2)
(vx1, vy1) = (vx0, vy0) + (ax0, ay0)*dt = (34.64 ft/sec, 20 ft/sec) + (0, -3.22 ft/sec) = (34.64, 16.78)
(ux1, uy1) = (ux0, uy0) + (vx0, vy0)*dt = (3.464 ft, 1.678 ft)
Take another time step of 0.1 seconds with these values as the start. Rinse, repeat....
You do this individually for both x- and y- axes.
You can make this slightly more real by making the initial height of the cannon ball equal to half the diameter of your cannon wheels.
You can add a small negative acceleration in the x-direction to simulate wind resistance.
Assume your target is off to the right along the x-axis.
If you fire with the cannon pointing straight up the equations will show the ball going up, slowing down under it reaches its apex, and then coming straight down. No hit, except perhaps on your head and the cannon.
If you fire with the cannon horizontal, the equations say the ball with move with constant velocity in the x-direction and only fall the initial height of the cannon. Your enemies will taunt you: "Air ball! Air ball!"
So if you want the ball to intersect with the ground (a.k.a. reach position y = 0) within some blast radius of your target's location, you'll have to play with the initial speed and the angle of the cannon from the horizontal.
You just need to use the equations of movement for each axis:
x(t)= x0 + v0*t + 1/2*a*t^2 #where x0 is the initial position, v0 is the initial velocity and a is the acceleration you are considering, all relatively to an axis
Now you need to define the instants at which you are calculating the position, as well as writing the values of velocity and acceleration in the correct units as #markusw suggested.
like this:
double calculateSpeed(double value) {
return value / 16.66;
}
And call it like this:
positionX = positionX + calculateSpeed(50);

Getting distance of a point in a 2d triangle without calculating perpendicular vectors?

Alright, so I'm trying to get the distance of a point in a 2d triangle without calculating perpendicular vectors.
float qd = Vector2f.dot(new Vector2f(pos.x, pos.z),
new Vector2f(normal.pos.x, normal.pos.z)) -
Vector2f.dot(new Vector2f(q.center.x, q.center.z),
new Vector2f(normal.pos.x, normal.pos.z));
That's the code I'm using. (Note: it's converting 3f vectors to 2d ones, but you don't have to worry about that). I need the result of the calculation to be between 0 and 1 I.E. 0.5 or something.
If I'm still not explaining right maybe this will help?
My question is: How do I get the distance of a point in a 2d triangle without calculating perpendicular vector's distance? I.E. if the triangle is facing up (y = -1) without any tilt
I would need the distance in the triangle without any X.
Edit1: About what you're saying, Banthar, This is what I got out of it, and it doesn't work, but it seems like it's close to working.
float d = (float) Math.sqrt( 0 /*cause the two x's should be the same */ + Math.pow(pos.z - q.max.z, 2));
float h = (float) Math.sqrt( 0 /*cause the two x's should be the same */ + Math.pow(q.min.z - q.max.z, 2));
float myDist = d/h;
Let's say your triangle is ABC and the point is P.
The number you are looking for is the distance from P to AB divided by the distance from C to AB.
This is the same as the ratio of the corresponding areas. So you can compute the two areas:
Area(ABP) / Area(ABC)
The best way to compute the triangle area depends on what information you have about your triangle.
If you have the vertices only, then you can use:
Area(ABP) / Area(ABC) = ( Ax*By - Ax*Py + Ay*Px - Ay*Bx + Bx*Py - By*Px ) /
( Ax*By - Ax*Cy + Ay*Cx - Ay*Bx + Bx*Cy - By*Cx )

Categories

Resources