I am looking to calculate lat and lng points of a circular provided a center point and radius. The code I currently have is below, the result is always an oval looking shape and not a circle.
double val = 2 * Math.PI / points;
for (int i = 0; i < points; i++)
{
double angle = val * i;
double newX = (dCenterX + radius * Math.Cos(angle));
double newY = (dCenterY + radius * Math.Sin(angle));
}
You can calculate these points using formula for Destination point given distance and bearing from start point
JavaScript: (all angles in radians)
var φ2 = Math.asin( Math.sin(φ1)*Math.cos(d/R) +
Math.cos(φ1)*Math.sin(d/R)*Math.cos(brng) );
var λ2 = λ1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(φ1),
Math.cos(d/R)-Math.sin(φ1)*Math.sin(φ2));
where φ is latitude, λ is longitude, θ is the bearing (clockwise from north), δ is the angular distance d/R; d being the distance travelled, R the earth’s radius
Related
I have a list of 2D coordinates that draw a shape, e.g. [{12, 14}, {22, 44}, {59, 33}, ...]
I'd like to be able to take this shape, and center it in a canvas of arbitrary size (let's say 400x400) and have it take as much space as possible.
I've figured out how to normalize the list so it's in the 0-1 range, but ended up being stuck there when trying to then scale it up to the desired size.
Any help would be appreciated!
Find minimal and maximal values for X and Y coordinates xmin, xmax, ymin, ymax
Calculate point cloud width and height, and middle coordinates
cw = xmax - xmin
ch = ymax - ymin
mx = (xmax + xmin) / 2
my = (ymax + ymin) / 2
Now find coefficient
if cw * canvas.height >= ch * canvas.width
coeff = canvas.width / cw
else
coeff = canvas.height / ch
Now get canvas center
centerx = canvas.width / 2
centery = canvas.height / 2
and apply the next transformation to every point (x,y):
screenx = centerx + coeff * (x - mx)
screeny = centery + coeff * (y - my)
I have a problem where I have to select all squares (think pixels) that are partially within a circle (even if the circle only cuts through a small corner of the square, but not if it goes through one of the corner vertices). The radius is an integer multiple of the pixel size.
The problem is that the center of the circle is between pixels, i.e. on the corner vertices of four pixels.
I want to visit each pixel only once.
For example, I would like to select all white pixels in the following images:
R = 8 px
R = 10 px
For a circle with the center in the center of a pixel, this wouldn't be a problem, and I could use the usual form of the Bresenham algorithm:
public void checkCircle(int x0, int y0, int radius) {
int x = radius;
int y = 0;
int err = -x;
while (x > 0) {
while (err <= 0) {
y++;
err += 2 * y + 1;
}
checkVLine(x0 + x, y0 - y, y0 + y);
checkVLine(x0 - x, y0 - y, y0 + y);
x--;
err -= 2 * x + 1;
}
checkVLine(x0, y0 - radius, y0 + radius);
}
public void checkVLine(int x, int y0, int y1) {
assert(y0 <= y1);
for (int y = y0; y <= y1; y++)
checkPixel(x, y);
}
Sadly, I don't see how to adapt it to support inter-pixel circles.
For the first quadrant - cell should be marked if its left bottom corner lies inside circle, so you can rasterize with simple loops
for dy = 0 to R-1
dx = 0
sq = R * R - dy * dy
while dx * dx < sq
mark (dx, dy)
mark (dx, -dy-1)
mark (-dx-1, dy)
mark (-dx-1, -dy-1)
To fill whole horizontal lines, you can calculate max value for dx
for dy = 0 to R-1
mdx = Floor(Sqrt(R * R - dy * dy))
fill line (-mdx-1,dy)-(mdx,dy)
fill line (-mdx-1,-dy-1)-(mdx,-dy-1)
I am working on a game that rotates an object on the z axis. I need to limit the total rotation to 80 degrees. I tried the following code, but it doesn't work. minAngle = -40.0f and maxAngle = 40.0f
Vector3 pos = transform.position;
pos.z = Mathf.Clamp(pos.z, minAngle, maxAngle);
transform.position = pos;
The code you posted clamps the z position. What you want is to use transform.rotation
void ClampRotation(float minAngle, float maxAngle, float clampAroundAngle = 0)
{
//clampAroundAngle is the angle you want the clamp to originate from
//For example a value of 90, with a min=-45 and max=45, will let the angle go 45 degrees away from 90
//Adjust to make 0 be right side up
clampAroundAngle += 180;
//Get the angle of the z axis and rotate it up side down
float z = transform.rotation.eulerAngles.z - clampAroundAngle;
z = WrapAngle(z);
//Move range to [-180, 180]
z -= 180;
//Clamp to desired range
z = Mathf.Clamp(z, minAngle, maxAngle);
//Move range back to [0, 360]
z += 180;
//Set the angle back to the transform and rotate it back to right side up
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, z + clampAroundAngle);
}
//Make sure angle is within 0,360 range
float WrapAngle(float angle)
{
//If its negative rotate until its positive
while (angle < 0)
angle += 360;
//If its to positive rotate until within range
return Mathf.Repeat(angle, 360);
}
Here's a static version of the nice solution by Imapler that, instead of changing the angle itself, it returns the campled angle, so it can be used with any axis.
public static float ClampAngle(
float currentValue,
float minAngle,
float maxAngle,
float clampAroundAngle = 0
) {
return Mathf.Clamp(
WrapAngle(currentValue - (clampAroundAngle + 180)) - 180,
minAngle,
maxAngle
) + 360 + clampAroundAngle;
}
public static float WrapAngle(float angle)
{
while (angle < 0) {
angle += 360;
}
return Mathf.Repeat(angle, 360);
}
Or if you don't expect to use the WrapAngle method, here's an all-in-one version:
public static float ClampAngle(
float currentValue,
float minAngle,
float maxAngle,
float clampAroundAngle = 0
) {
float angle = currentValue - (clampAroundAngle + 180);
while (angle < 0) {
angle += 360;
}
angle = Mathf.Repeat(angle, 360);
return Mathf.Clamp(
angle - 180,
minAngle,
maxAngle
) + 360 + clampAroundAngle;
}
So now you can do:
transform.localEulerAngles.x = YourMathf.ClampAngle(
transform.localEulerAngles.x,
minX,
maxX
);
I have a bezier curve defined by start point, end point and 2 control points (parameters of this: http://www.w3schools.com/tags/canvas_beziercurveto.asp).
First, I need to calculate width and height of this curve. If I make rectangle around a curve, its width and height is what I need.
Then I need to start point (x,y of left top corner) of this rectangle.
How can I calculate that ? Thanks.
For true bounds, you need to compute the extremities of the curve's component functions, then plug those into the bezier function for the (x,y) coordinates for each extremity. I cover this over at http://pomax.github.io/bezierinfo/#extremities, which also explains how to do most of the steps required to get there in the text leading up to the extremities section. paragraphs 11 and 12/13 then cover bounding boxes (plain, which you're probably interested in, and tight, respectively)
I found approximate solution in some other topic (I don't remember which one) but here is simple JS function to calculate it:
function getCurveBoundary(ax, ay, bx, by, cx, cy, dx, dy) {
var tobx = bx - ax;
var toby = by - ay;
var tocx = cx - bx;
var tocy = cy - by;
var todx = dx - cx;
var tody = dy - cy;
var step = 1 / 40; // precission
var d, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, i, minx, miny, maxx, maxy;
function min(num1, num2) {
if (num1 > num2)
return num2;
if (num1 < num2)
return num1;
return num1;
}
function max(num1, num2) {
if (num1 > num2)
return num1;
if (num1 < num2)
return num2;
return num1;
}
for (var i = 0; i < 41; i++)
{
d = i * step;
px = ax + d * tobx;
py = ay + d * toby;
qx = bx + d * tocx;
qy = by + d * tocy;
rx = cx + d * todx;
ry = cy + d * tody;
toqx = qx - px;
toqy = qy - py;
torx = rx - qx;
tory = ry - qy;
sx = px + d * toqx;
sy = py + d * toqy;
tx = qx + d * torx;
ty = qy + d * tory;
totx = tx - sx;
toty = ty - sy;
x = sx + d * totx;
y = sy + d * toty;
if (i == 0)
{
minx = x;
miny = y;
maxx = x;
maxy = y;
}
else
{
minx = min(minx, x);
miny = min(miny, y);
maxx = max(maxx, x);
maxy = max(maxy, y);
}
}
return {x: Math.round(minx), y: Math.round(miny), width: Math.round(maxx - minx), height: Math.round(maxy - miny)};
}
If you're looking for an approximate solution, it's pretty easy to compute a solution that's always big enough to cover the curve, but might be too big.
Beziers satisfy the 'convex hull property' which means that you can take a bounding box of your control points and that will bound the curve itself.
If you're looking for something more accurate, then the simplest way is to evaluate a bunch of different points on the curve and take the bounding box of those points on the curve. You can vary the number of points you test in order to change the quality/speed tradeoff.
If you're looking for something that directly computes the exact answer then what you need is a root finder to look for extrema of the functions x(t) and y(t).
I am trying to determine the point at which a line segment intersect a circle. For example, given any point between P0 and P3 (And also assuming that you know the radius), what is the easiest method to determine P3?
Generally,
find the angle between P0 and P1
draw a line at that angle from P0 at a distance r, which will give you P3
In pseudocode,
theta = atan2(P1.y-P0.y, P1.x-P0.x)
P3.x = P0.x + r * cos(theta)
P3.y = P0.y + r * sin(theta)
From the center of the circle and the radius you can write the equation describing the circle.
From the two points P0 and P1 you can write the equation describing the line.
So you have 2 equations in 2 unknowns, which you can solved through substitution.
Let (x0,y0) = coordinates of the point P0
And (x1,y1) = coordinates of the point P1
And r = the radius of the circle.
The equation for the circle is:
(x-x0)^2 + (y-y0)^2 = r^2
The equation for the line is:
(y-y0) = M(x-x0) // where M = (y1-y0)/(x1-x0)
Plugging the 2nd equation into the first gives:
(x-x0)^2*(1 + M^2) = r^2
x - x0 = r/sqrt(1+M^2)
Similarly you can find that
y - y0 = r/sqrt(1+1/M^2)
The point (x,y) is the intersection point between the line and the circle, (x,y) is your answer.
P3 = (x0 + r/sqrt(1+M^2), y0 + r/sqrt(1+1/M^2))
Go for this code..its save the time
private boolean circleLineIntersect(float x1, float y1, float x2, float y2, float cx, float cy, float cr ) {
float dx = x2 - x1;
float dy = y2 - y1;
float a = dx * dx + dy * dy;
float b = 2 * (dx * (x1 - cx) + dy * (y1 - cy));
float c = cx * cx + cy * cy;
c += x1 * x1 + y1 * y1;
c -= 2 * (cx * x1 + cy * y1);
c -= cr * cr;
float bb4ac = b * b - 4 * a * c;
// return false No collision
// return true Collision
return bb4ac >= 0;
}
You have a system of equations. The circle is defined by: x^2 + y^2 = r^2. The line is defined by y = y0 + [(y1 - y0) / (x1 - x0)]·(x - x0). Substitute the second into the first, you get x^2 + (y0 + [(y1 - y0) / (x1 - x0)]·(x - x0))^2 = r^2. Solve this and you'll get 0-2 values for x. Plug them back into either equation to get your values for y.
MATLAB CODE
function [ flag] = circleLineSegmentIntersection2(Ax, Ay, Bx, By, Cx, Cy, R)
% A and B are two end points of a line segment and C is the center of
the circle, % R is the radius of the circle. THis function compute
the closest point fron C to the segment % If the distance to the
closest point > R return 0 else 1
Dx = Bx-Ax;
Dy = By-Ay;
LAB = (Dx^2 + Dy^2);
t = ((Cx - Ax) * Dx + (Cy - Ay) * Dy) / LAB;
if t > 1
t=1;
elseif t<0
t=0;
end;
nearestX = Ax + t * Dx;
nearestY = Ay + t * Dy;
dist = sqrt( (nearestX-Cx)^2 + (nearestY-Cy)^2 );
if (dist > R )
flag=0;
else
flag=1;
end
end