I want to generate N points within a square (uniformly).
how i can achieve this ?
Pretty cool problem, and a lot harder than I imagined but here's the idea. There are papers on this for n-gons but I will just do the square. So uniform distribution from a circle is a common problem and you can't just sample the radius, r, and the angle, theta, independently since more weight is given to a large radius, ie if we take an infinitismally small annulus, you have more area coming from a larger radius further away from the center so we sample uniformly from r^2 since the area is a function of r^2.
Now the idea is similar for a rectangle, its symmetry lends itself to be captured with a some measure of rotation (angle) and distance from origin (radius) but notice that the radius changes dramatically as you rotate about a circle, goes up then down then up then down. we need a way to prescribe the radius based on the angle so its mass at about any given point is uniform.
Consider the following construction (we can orient the square such that it sits on one of its sides but this is more intuitive) Sorry my diagrams are badly drawn
A
X
B O C
D
Here is our square, with A,B,C,D being the corners and O being the origin. We'll explain X later. Let's start at the point C and rotate counterclockwise and the angle will be denoted Theta. X is the point of intersection with the edge of the square if we draw a line from O with angle Theta. In other words, X = r(Theta). What we are trying to do is capture the distance r as a function of theta as to make this a uniform probability distribution of Theta. That's the whole idea..
we can write the following with the law of sines
Sin(pi - Theta - pi/4)/c = sin(pi/4)/r(Theta) where C sits at (c,0)
do some algebra and arrive at
r(Theta) = sqrt(2)*c / (2sin(3pi/4 - Theta)
now we need a constant k such that integrating k*r(Theta) will give you 1, which you can easily do.
I got
a*sin(pi/4)ln|tan((Theta+pi/4)/2)| evaluated from 0 to pi/4
you've successfully build the p.d.f. (probability distribution function) for your r(Theta), now calculate the c.d.f. (cumulative distribution function), set it to uniform and get a closed form expression for your Theta.
up to now we've constructed the random Theta, to build the radius r, realize that much like a circle we have more mass further away and we can construct it as
R = r(Theta)/s where s is uniform from 0 to 1.
we use r(Theta) because it's the max possible value given Theta.
Related
For a problem, we have to graph n equidistant points around a circle. I didn't know how to do that, so I searched it up and found a solution, but I don't know why it works. Here is the equations I used for each point.
StdDraw.point(Math.cos((i * 2 * Math.PI) / n) + 1, Math.sin((i * 2 * Math.PI) / n) + 1);
This was put in a for loop, so "i" is what number point it is and "n" is the number of points that need to be graphed. I added 1 at the end to translate it to fit inside the canvas.
Does anyone know why it works?
Sine and Cosine output curves model all of the points along the circumference of a circle and they do this by being fed all of the possible angles that exist within a circle i.e 2pi if you use radians. Now, if you feed 2pi*(i/n) to sine and cosine that is giving each respective function n angles between 0 and 2*pi, and the output each spits out is then equidistant because you fed in equidistant angles, so you will receive equidistant points that fall at the ends of those angles that you fed in.
Look at a gif of sine and cosine around a circle, then a graph of sine and cosine and more will make sense.
I have a position given in decimal degrees (x.xxxxxxxx and y.yyyyyyyy). I need to draw a rectangle around it. The center of the rectangle matches the position. The dimensions of the rectangle is given in meters and it has a rotation ranging from 0-360 degrees.
Question
How can I calculate the four corners of the rectangle and return the result as four decimal degree values? Like arrayOf<LatLon> getRectangle(LatLon position, int rectWidthCm, int rectLengthCm, double rectRotation).
Example
I have a position given in LatLon format with two two values: latitude and longitude. We will assume this location is precise.
The main task is to draw a rectangle based on this position in a Google Maps chart. The rectangle can have any dimentions but let's use these in this example: Width = 0.9 meter and Length = 1.2 meters. Any heading may also be given so lets use this heading: 45. 0 Is north and going clockwise round (east = 90, south = 180 and west = 270). When the rectangle is pointing north it has the length in the north/south direction. Finally, the rectangle center should be equal to the given position.
Note: The project setup is an Android application with Kotlin support and a google maps chart. I am interested in a modern approach to this problem. Regarding precision loss it should at most be within centimeters.
I understand that you are looking for a function geo_rect(x,y,w,h,a) with the following parameters
x is the longitude according to WGS84
y is the latitude
w is the width of the rectangle in meters
h is the height of the rectangle in meters
a is the angle to which the rectangle is turned from w being horizontal (meaning pointing exactly West to East). I suggest to allow values ranging within the open interval (-90°,90°) as this makes the math either to understand.
Your function getRectangle(LatLon position, int rectWidthCm, int rectLengthCm, double rectRotation) deliver all the required information, you need a small wrapper function which determines w, h, and a from rectWidthCm, rectLengthCm and rectRotation, with the latter being within [0°,360°).
The function geo_rect() will return an arrayOf<LatLon> of length four, namely the coordinates of all four corners, starting on the top left and then going clockwise. We will refer to the points as P_NE,P_NW,P_SE, and P_SW respectively.
Assumptions
In order to keep things mathematically feasible, we make some assumptions
We assume that we can use as approximation that the rectangle is a plane, which is okay if w ~ h << r with r = 6378 km being the radius of the Earth.
We further assume that the Earth is a ideal sphere rather than an ellipsoid or even more bumpy. For an accessible article on that issue, see e.g. Zachary C. Eilon's blog
Basic structure of the algorithm
The algorithm could be structured as follows:
Determine the distance d from (x,y) to all four end points. Because of our first assumption we can use simple Euclidian geometry rather than intricate Spherical geometry. Pythagoras holds: d^2 = (w/2)^2 + (h/2)^2.
We also need the four bearings, e.g. b_NW for the angle between the vector pointing to the North Pole and the vector pointing from (x,y) to point P_NW.
Given the information (x,y,d,b_NW, b_NE, b_SW, b_SE) from the previous steps, we can now follow Get lat/long given current point, distance and bearing to calculate the position of all four points. This is the mathematically hard part where I suggest to use a well-established and tested library for.
Last but not least, let us double-check whether the calculation went well by evaluating Great circle distances between some or all pairs of points. For instance d(P_NE,P_NW) should approximately be w, d(P_NW,P_SW) should approximately be h. Don't be surprised if there is actually a difference - this errors are due the assumptions we made. Normal GPS under usual conditions will anyhow not allow you to determine your position up to the centimeter, you will need DPGS for that.
Further reading
At https://www.movable-type.co.uk/scripts/latlong-vectors.html you can experiment online to determine a destination point along a great-circle given the distance and bearing from a start point (in our case: the center of the rectangle).
Old, but amazingly documented and well tested tool kit for geo-applications in general are the https://www.generic-mapping-tools.org/ - you might want to look at the command gmtvector.
If you are looking for java implementations, I found e.g.
https://introcs.cs.princeton.edu/java/12types/GreatCircle.java.html on of many implementations for calculating great circle distances
Need a standalone Java library for performing spatial calculations on lat/lon data
Calculate point based on distance and direction
In a vector graphics program I am writing using Java, ideally any shape would be represented by a modified form of the Path2D class, which uses quadratic Bezier curves. Ideally ellipses would be represented as Path2D objects as well. There is heavy documentation on the internet for approximating quadrants of a circle using cubic Bezier curves, but using the Path2D class, cubic Bezier curves are not possible. I have been using Desmos to try to find an approximation of the octant of a circle, and the middle point (between the two control points) for a circle of radius 1 centered at (0, 0) is approximately (0.993, 0.412). Surely there is some irrational number that can more precisely be expressed as a formula using square roots or trigonometric functions.
I have attempted using the formula 4*tan(pi/(2*n))/3. Either that formula does not apply to octants or it was poorly explained where I found it.
t would help if you said where you found it - the formulae for arbitrary angles (which obviously includes octants, just plug in PI/4 as your angle) are rather different from what you show. Find the real formulae, and explanation, over on https://pomax.github.io/bezierinfo/#circles.
Quadratic curves are dead simple in the sense that the control point is a linear intersection of the end point tangents. So, given start point (1,0) with vertical tangent (because it's a circle, that's how circles work) and end point (cos(phi), sin(phi)) for some angle phi, with tangent (sin(phi), -cos(phi)), we can determine the control point for this curve as:
Cx = cos(phi) - b * sin(phi)
Cy = sin(phi) + b * cos(phi)
where:
cos(phi) - 1
b = ------------
sin(phi)
(The actual maths here is explained in the link above).
Plugging in PI/4 to compute the first octant means we get:
Cx = 1 (obviously; it's a vertical tangent, so the x coordinate is fixed)
Cy = sqrt(2) - 1
And you're done: you don't need to derive any other values, because all the other octants are just reflections of these values that you literally just write out on some paper by drawing a circle, draw lines to show octants, mark the first octant with its coordinate values, and then go "oh, obviously the other coordinates are: ..." -- also the above formulae are for circles with radius 1, but you know how to multiply so you know how to scale the values so that they match your desired circle.
I would be curious why you want quadratic curves, though, because they're objectively pretty terrible compared to cubics. For example: you need 16 points to model a circle with quadratic octants, whereas you only need 12 points for cubic quarters, which have higher precision.
Also, even if you're dead set only ever using quadratics, users of your software might move to other software. They expect cubics to be available to the point where they will petition you for them if the rest of your software is worth using. Plan for that, or ideally just support quadratic and cubic from the start. After all, SVG etc. already do.
I've looked many places and haven't found any resources (that I understand) that explain how to turn the standard Midpoint circle algorithm (which uses octants to create the whole circle) into only considering a specific 'slice' of the circle. I'm using this to find the tiles within a line of sight radius.
the code I'm using is the basic Wikipedia code of how to implement the algorithm.
I'm using java inside "Processing" to prototype things out.
I'm trying to understand how this algorithm works so I can modify it, but I'm having trouble.
The midpoint algorithm or Bresenham algorithm can be extended with a condition if the point you are rasterizing falls into the range you have specified by the angles (points). To get the range you would have to find the starting and ending point on the circle. This can be easily accomplished with help of polar coordinates. If we have a circle with radius r, angle theta and center C(x0,y0) the point on the circle can be computed as pCircle(x,y) = (x0 + r * cos theta, y0 + r * sin theta). Note that the angle is in radians.
Lets say I have an angle... what would be a reasonable way to go about finding the next point of where the ball would be?
Variables: bSpeed, bAngle, Ball.x, Ball.y
You knwon when you do c^2 = a^2 + b^2... is there a way you could find how long c^2 could be and actually "draw" it out and then use speed to go only part of that... with that find a^2 and b^2 so you can actually have a x and a y to draw the ball...
Thanks ahead of time! (BTW, I don't need code... just reasoning and wisdom)
Your 4 variables are effectively a vector - where the vector is a measure of both direction and magnitude/velocity (i.e. what you've represented as bSpeed and bAngle). Using this representation means that Ball.x and Ball.y simply become the horizontal and vertical components of the vector.
Given a vector called v1 we can calculate the movement in the x and y axis as follows...
xVelocityOfBall = v1.magnitude * cos(v1.angle);
yVelocityOfBall = v1.magnitude * sin(v1.angle);
GPWiki (Games Programming Wiki) is a great resource for anything maths/physics for games development. Here's a handy link to their vector page
delta_x = speed*cos(angle)
delta_y = speed*sin(angle)
new_x = x+delta_x
new_y = y+delta_y
and then you need just change speed and angle of ball in the case of wall strike)
Open up your textbooks on Sin, Cos and Tan since you're using bAngle. Specifically you'll probably be looking Sin for the vertical motion and Cos for the horizontal motion. Depending on where you've defined degree 0 to face.
Also, you could consider caching the horizontal and vertical speeds since Sin and Cos are expensive
You probably will need to consider the physics of the movement that the pong player is moving also. For example, if a player's paddle is speeding to the left as it contacts the ball, the ball will need to speed up wrt to the left direction. This represents transfer of momentum in physics. The general system of equations in the x and y directions will always be:
mass*velocity (in x) = the sum of the mass*velocity of all objects in x
mass*velocity (in y) = the sum of the mass*velocity of all objects in y
generally speaking sine you always have the speed of the ball in x and y all you need to do is determine the masses of both the ball and the paddles (i suppose that's up to you but I suggest making them the same for ease of calculation).
In terms of solving for the angle, it's very simple, you would just make sure the reflection is equal. If the ball is approaching a paddle (or wall) from a 60 degree incident, then the bounce should also be at a 60 degree incident.
First, convert the angle to a vector using the sin and cos functions. This tells you the relative x-speed and y-speed of the ball. Then, to find out how far the ball actually went, multiply these numbers by the ball's speed and time-of-flight. Finally, add to the ball's starting position. This gives you the ball's ending position.
In a pong game, the ball may hit an object, in which case you need to correct for the change in velocity.