Finding Y values on a circle - geometry-surface

I want to find the Y values on a circle. Given is the center, the radius and some X values.
e.g. : center is 10,10, radius is 5. What is the Y value if X=(centerX - radius), X=centerX - radius +1, ... X = centerX + radius.
I do understand that there will be 2 results for each X.
I need this equation to draw a circle on a LED matrix using an Arduino (C++)
Starting from the formula
(x-a)² + (y-b)² = r²
where
r = radius
a = centerX
b = centerY
x = x coordinate of point on circle
y = y coordinate of point on circle
The equation for y should be :
y = sq(r²-x² + 2a - a² + 2b - b²)
but I don't get a circle on my matrix ...
When I calculate y manually for some x values, I mostly come to a negative number before I take the square root. And of course a square root from a negative number does not exist.
Of course the compiler does not give any error messages.
y = sq((r * r) - (x * x) + (2 * a) - (a * a) + (2 * b) - (b * b))

Hold it, hold it ! :)
Let me first correct my code ...
instead of using "sq", I should have used "sqrt"...
I'll get back here soon to let you know if this was the culprit ...
thanks to those who read and tried to find a solution ...
Oh ... Also found a flaw in my equation ...
(x-a)² + (y-b)² = r²
(y-b)² = r² - (x-a)² (OK?)
y² - 2by + b² = r² - (x-a)² (OK?)
y² - 2by = r² - (x-a)² -b² (OK?)
Now we have y twice on the left... I can't transfer one of the y's to the right 'cause the result would be IN the equation, right ?
So,what now ???

You should do sqrt(r^2 - (X-a)^2) + b

Related

determining algorithm for calculating a point intersecting a circle where the segment crosses from inside to the outside of the circle

I have a line segment between points A and B. A is inside a circle with a center at 0,0 with a radius of R. I am stumped trying to come up with an efficient way to calculate the intersection of line segment AB with this circle.
This is a mere second degree equation resolution
Line is y=A.x +B , where A and B are constants
Circle is y^2=R^2 - x^2 , where R is the radius, and circle center is 0,0
so (A.x+B)^2=R^2-x^2 => A^2.x^2 +2.A.x.B +B^2 =R^2 -x^2 =>
(A^2+1).x^2 + 2.A.B.x +B^2-R^2 =0
The algorithm is :
let P=A^2+1 , G=2.A.B , H=B^2-R^2
The equation is : P.x^2 + G.x + H=0
that gives 3 cases depending on delta
delta=G^2-4*P*H
If delta<0 => no intersections
if delta=0 => intersect in 1 point : x=-G/2*P and y=Ax+B
if delta>0 => intersect in 2 points : x1=(-G-sqrt(delta))/(2*P) , y1=Ax1+B and x2=(-G+sqrt(delta))/(2*P) ,y2=Ax2+B (where sqrt is the square root)
Then you just have to determine which of the two resultant answers give a point that is between A and B.
Let's call two resultants I1 and I2. To determine which one is the answer, you need to check directions of A->I1 and A->I2 vectors against A->B, where A is the point that is located inside the circle:
% line: y = mx + b
m = (yB - yA) / (xB - xA);
b = yA - m * xA;
% circle: x^2 + y^2 = r^2
% intersection: x^2 + (mx + b)^2 = r^2
% ... x^2 + m^2x^2 + b^2 + 2mbx - r^2 = 0
% ... (1 + m^2)x^2 + 2mbx + (b^2 - r^2) = 0
A = 1 + m^2;
B = 2 * m * b;
C = b^2 - r^2;
sqrtD = sqrt(B^2 - 4*A*C);
xI = (-B+sqrtD) / (2*A);
yI = m * xI + b;
if (abs(atan2(yB - yA, xB - xA)-atan2(yI - yA, xI - xA)) > 1e-5)
xI = (-B-sqrtD) / (2*A);
yI = m * xI + b;
end
Remark #1: I didn't check the delta for being negative, since you said one point is inside the circle and the other is outside of it.
Remark #2: You need to cover the special case where A == B.
Remark #3: You need to cover the special case where xA == xB.
Remark #4: You can pick the correct answer with much less cost than finding the slope of two vectors, calculating the absolute variance between them and comparing the result with an epsilon! :)

How to find given 2D point position based on axis system

I have a axis system(origin,u direction,v direction).How to know given 2D point lie on the line which is used to denote the u or v direction line(ie, u=0 or v =0)?
The axis OU has equation
Uy.(X - Ox) - Ux.(Y - Oy) = 0
and similarly for OV
Vy.(X - Ox) - Vx.(Y - Oy) = 0
Because of rounding errors, strict equality to zero will not hold, but if the vectors U and V are normalized,
|Uy.(X - Ox) - Ux.(Y - Oy)|
and
|Vy.(X - Ox) - Vx.(Y - Oy)|
are the shortest distances from the point (X, Y) to the axes.
If "given 2D point" P coordinates are presented in fixed coordinate system, then you have to represent vector P-origin in o-u-v basis.
op = P - origin
s * u.x + t * v.x = op.x
s * u.y + t * v.y = op.y
Solve last system of linear equations for unknown coefficients s and t. Check for zero coefficients.

Finding coordinates of Hexagonal path

I am trying to convert a movement along a straight line ( 2 points) to a movement along Hexagonal path, I tried different formula and did not work.
I would like to find out the coordinates of P,Q,R,M based on A and B.
I hope someone suggest a better formula which gives me the coordinates to move a long Hexagonal path.
If you are familiar with complex numbers (and assuming this is a regular hexagon),
D = B - A
P = A + D( 1 + sqrt(3)i )/4
Q = A + D( 3 + sqrt(3)i )/4
R = A + D( 1 - sqrt(3)i )/4
M = A + D( 3 - sqrt(3)i )/4
EDIT:
If you are not familiar with complex numbers, we should not attempt to use them here. They are a wonderful tool, but not easy to grasp at first. Let's do it the long way:
A = (Ax, Ay)
B = (Bx, By)
D = B - A = (Dx, Dy) where Dx=Ax-Bx and Dy=Ay-By
P = (Ax + Dx/4 - sqrt(3)Dy/4, Ay + Dy/4 + sqrt(3)Dx/4)
Q = (Ax + 3Dx/4 - sqrt(3)Dy/4, Ay + 3Dy/4 + sqrt(3)Dx/4)
R = (Ax + Dx/4 + sqrt(3)Dy/4, Ay + Dy/4 - sqrt(3)Dx/4)
M = (Ax + 3Dx/4 + sqrt(3)Dy/4, Ay + 3Dy/4 - sqrt(3)Dx/4)
This is easier to conceptualize if you imagine your hexagon as being made up of vectors - lines with a magnitude (distance) and a direction (angle from the west-to-east horizon rotating counterclockwise).
Call the vector from A to B D. If you use some trigonometry to figure out the geometry of a hexagon, D's magnitude is two times the length of the side of the hexagon. So, we can use this to construct vectors that are as large as our other hexagon sides, and thereby get the hexagon's other points.
Take the vector D, halve its magnitude, rotate it 60 degrees ccw and add this new vector to A's position. This gives you P.
Do the same thing but rotate it 60 degrees cw and add this to A's position. This gives you R.
Similarly, Q is the vector D halved, rotated 60 degrees cw, inverted and added to B's position.
Finally, M is the vector D halved, rotated 60 degrees ccw, inverted and added to B's position.
(To convert a vector into x distance moved and y distance moved, multiply the magnitude by the cos of the angle and by the sin of the angle respectively. Make sure you are using radians if radians are needed and degrees if degrees are needed.)

Manhattan Distance between tiles in a hexagonal grid

For a square grid the euclidean distance between tile A and B is:
distance = sqrt(sqr(x1-x2)) + sqr(y1-y2))
For an actor constrained to move along a square grid, the Manhattan Distance is a better measure of actual distance we must travel:
manhattanDistance = abs(x1-x2) + abs(y1-y2))
How do I get the manhattan distance between two tiles in a hexagonal grid as illustrated with the red and blue lines below?
I once set up a hexagonal coordinate system in a game so that the y-axis was at a 60-degree angle to the x-axis. This avoids the odd-even row distinction.
(source: althenia.net)
The distance in this coordinate system is:
dx = x1 - x0
dy = y1 - y0
if sign(dx) == sign(dy)
abs(dx + dy)
else
max(abs(dx), abs(dy))
You can convert (x', y) from your coordinate system to (x, y) in this one using:
x = x' - floor(y/2)
So dx becomes:
dx = x1' - x0' - floor(y1/2) + floor(y0/2)
Careful with rounding when implementing this using integer division. In C for int y floor(y/2) is (y%2 ? y-1 : y)/2.
I assume that you want the Euclidean distance in the plane between the centers of two tiles that are identified as you showed in the figure. I think this can be derived from the figure. For any x and y, the vector from the center of tile (x, y) to the center of tile (x + dx, y) is (dx, 0). The vector from the center of tile (x, y) and (x, y + dy) is (-dy / 2, dy*sqrt(3) / 2). A simple vector addition gives a vector of (dx - (dy / 2), dy * sqrt(3) / 2) between (x, y) and (x + dx, y + dy) for any x, y, dx, and dy. The total distance is then the norm of the vector: sqrt((dx - (dy / 2)) ^ 2 + 3 * dy * dy / 4)
If you want the straight-line distance:
double dy = y2 - y1;
double dx = x2 - x1;
// if the height is odd
if ((int)dy & 1){
// whether the upper x coord is displaced left or right
// depends on whether the y1 coordinate is odd
dx += ((y1 & 1) ? -0.5 : 0.5);
}
double dis = sqrt(dx*dx + dy*dy);
What I'm trying to say is, if dy is even, it's just a rectangular space. If dy is odd, the position of the upper right corner is 1/2 unit to the left or to the right.
A straight forward answer for this question is not possible. The answer of this question is very much related to how you organize your tiles in the memory. I use odd-q vertical layout and with the following matlab code gives me the right answer always.
function f = offset_distance(x1,y1,x2,y2)
ac = offset_to_cube(x1,y1);
bc = offset_to_cube(x2,y2);
f = cube_distance(ac, bc);
end
function f = offset_to_cube(row,col)
%x = col - (row - (row&1)) / 2;
x = col - (row - mod(row,2)) / 2;
z = row;
y = -x-z;
f = [x,z,y];
end
function f= cube_distance(p1,p2)
a = abs( p1(1,1) - p2(1,1));
b = abs( p1(1,2) - p2(1,2));
c = abs( p1(1,3) - p2(1,3));
f = max([a,b,c]);
end
Here is a matlab testing code
sx = 6;
sy = 1;
for i = 0:7
for j = 0:5
k = offset_distance(sx,sy,i,j);
disp(['(',num2str(sx),',',num2str(sy),')->(',num2str(i),',',num2str(j),')=',num2str(k)])
end
end
For mathematical details of this solution visit: http://www.redblobgames.com/grids/hexagons/ . You can get a full hextile library at: http://www.redblobgames.com/grids/hexagons/implementation.html
This sounds like a job for the Bresenham line algorithm. You can use that to count the number of segments to get from A to B, and that will tell you the path distance.
If you define the different hexagons as a graph, you can get the shortest path from node A to node B. Since the distance from the hexagon centers is constant, set that as the edge weight.
This will probably be inefficient for large fields though.

Draw a point a set distance away from a base point

I'm trying to figure out an algorithm for finding a random point a set distance away from a base point. So for example:
This could just be basic maths and my brain not working yet (forgive me, haven't had my coffee yet :) ), but I've been trying to work this out on paper and I'm not getting anywhere.
coordinate of point on circle with radius R and center (xc, yc):
x = xc + R*cos(a);
y = yc + R*sin(a);
changing value of angle a from 0 to 2*PI you can find any point on circumference.
Use the angle from the verticle as your random input.
Pseudocode:
angle = rand(0,1)
x = cos(angle * 2 * pi) * Radius + x_centre
y = sin(angle * 2 * pi) * Radius + y_centre
Basic Pythagoras.
Pick random number between 0 and 50 and solve h^2 = a^2 + b^2
Add a few random descisions on direction.

Resources