I have no idea how to do this. I need to draw two lines that make an X through a circle, where the starting and end points would be on the circumference of the circle. If anybody could even give me a direction to go in to do this, it'd be appreciated.
Get the maths right first.
The most general case of circle-line intersection is described here: http://mathworld.wolfram.com/Circle-LineIntersection.html
But if the center of the circle is the origin, its radius is 1, and the lines are forming an x, so a 45 degree angle with the horizontal and vertical axes, it is quite a bit more simple:
The circle is defined by
x2 + y2 = 1
The line with 45 degree slope is defined by
y = x
Their intersections are the points (x,y) where both statements are true so
x2 + x2 = 1
2 x2 = 1
x2 = 1/2
x = sqrt(1/2) or x = -sqrt(1/2) and y = x
so points (sqrt(1/2), sqrt(1/2)) and (-sqrt(1/2), -sqrt(1/2))
Same for the other line.
One line goes from (-sqrt(0.5), -sqrt(0.5)) (bottom left) to (sqrt(0.5), sqrt(0.5)) (top right) and the other from (-sqrt(0.5), sqrt(0.5)) (top left) to (sqrt(0.5), -sqrt(0.5)) (bottom right).
On Wolfram Alpha
Related
I am programming a raycaster in JavaScript. I am having trouble finding or implementing an algorithm for the raycast. Currently I am trying out the cast in the following style.
Theres an grid with equal block width and height. My player has a position within the grid, a direction as an angle 0 - 360 degrees where hes looking at. In the first step I need to figure out the distace from my Player to the Green dot at the Grid Intersection. I know that the Green Point is at the Intersection therefore i can figure out the length of the red line. Theres an right angle at the intersection. When I ve calculated the distance or x and y position of the green dot I have to do a simular thing in the 2nd step. The distance of the orange line is known, the position of the green dot and the angle is known. Again the right angle is on the intersecting border line.
I am not even sure if its possible this way, but maybe you got any other idea how I should then work it out. Thank you very much.
(Apologies for formatting below; I'm tapping this out on a phone)
From trigonometry, cos(aplha) = (length of red line)/(length of hypotenuse).
Therefore: length of hypotenuse = (length of red line)/cos(alpha).
You'd use sin for a vertical intersection.
A word of caution though: if you think about what would happen when the player is looking directly at a wall, all the lengths should be the same so that it's a constant height on screen, but they'll actually be different because the diagonals are different. You need to multiply by cos of the relative angle between the player's direction and the casting direction (so, if you've a 60 degree field of view then 0 at the centre of the display, off to +30 at one end and down to -30 at the other).
Also don't fall into the common trap of thinking that the angles you cast at should be evenly spaced. Think again of a person looking directly at a wall and use atan to get the proper relative angles.
The parametric equations of the ray read
X = x + t cos α, Y = y + t sin α
with t>0.
Assuming a unit grid (but you can rescale), and the angle in the first quadrant, the first intersections with the grid are
X = ceiling(x) => t = (X - x) / cos α => Y = y + (X - x) . tan α
and
Y = ceiling(y) => t = (Y - y) / sin α => X = x + (Y - y) . cot α
The smallest of the two t will tell you which of the horizontal and vertical is met first.
The next intersections are with X = ceiling(x) + i, and Y = ceiling(y) + j, hence the Y increase in steps tan α and the X in steps cot α.
For the other quadrants, the ceiling's are replaced by floor's.
I writing a python program in which a circle bounces off of user drawn lines. There are multiple circles that bounce off the wall. For each one, the shortest distance from the center of the circle and the ball should be calculated. I would prefer if this code was very efficient because my current algorithm lags the computer a lot. If point a is the starting point ,and point b is the end point, and point c is the center, and r is the radius, how would I calculate the shortest distance between the ball? This algorithm should also work if the X coordinate of the ball is out of range of x coordinates in segment AB.
Please post python code
Any help would be appreciated!
Here's what I have so far:
lineList is a list with 4 values that contains beginning and end coordinates of the user drawn lines
center is the center of the ball
global lineList, numobjects
if not(0 in lineList):
beginCoord = [lineList[0],lineList[1]]
endCoord = [lineList[2]-500,lineList[3]-500]
center = [xCoordinate[i],yCoordinate[i]+15]
distance1 = math.sqrt((lineList[1] - center[1])**2 + (lineList[0] - center[0])**2)
slope1 = math.tan((lineList[1] - lineList[3]) / (lineList[0] - lineList[2]))
try:
slope2 = math.tan((center[1] - beginCoord[1])/(center[0]-beginCoord[0]))
angle1 = slope2 + slope1
circleDistance = distance1 * math.sin(angle1)
except:
#If the circle is directly above beginCoord
circleDistance = center[1] - lineList[1]
global numbounces
if circleDistance < 2 and circleDistance > -2:
print(circleDistance)
b = False
b2=False
if xCoordinate[i] < 0:
xCoordinate[i] += 1
speed1[i] *= -1
b=True
elif xCoordinate[i] > 0:
xCoordinate[i] -= 1
speed1[i] *= -1
b=True
if yCoordinate[i] < 0:
yCoordinate[i] += 1
speed2[i] *= -1
b2=True
elif yCoordinate[i] > 0:
yCoordinate[i] -= 1
speed2[i] *= -1
b2=True
if b and b2:
#Only delete the line if the ball reversed directions
numbounces += 1
#Add a ball after 5 bounces
if numbounces % 5 == 0 and numbounces != 0:
numobjects = 1
getData(numobjects)
canvas.delete("line")
lineList = [0,0,0,0]
To be correct we are not speaking not about lines, but rather segments.
I would suggest the following idea:
Since the ball is moving in some direction, the only points that might collide with something lie on a 180° arc - the part that is moving forward. Meaning at some point of time when you check for collision you have to check whether any of those points collided with something. The more points you check, the better the precision of the collision in time, but worse the complexity.
Checking the collision: you check whether any of the points is in between the extremes of the segment. You can do this by first checking the coordinates (example is given looking at your drawn line, meaning A.x < B.x and A.y > B.y) if (A.x <= point.x <= B.x && A.y >= point.y >= B.y if the condition satisfies, you check whether the 3 points form a line. Since you have already the coordinates of A and B you can deduce the equation of the line and check whether the point satisfies it.
In short: you check if the point satisfies the equation of the line and is inside the rectangle defined by the 2 points.
How to get the points you have to check: assuming 2k+1 is the number of points you want to check at some time, C is your center r the radius and V the vector of motion. Then the number of points from the left side of the direction vector and from the right side will be equal and be k (+1 point at the intersection of the circle and the motion vector). Then 90° / k is one angular division. Since you know the motion vector, you can calculate the angle between it and the horizontal line (let it be angle). You keep adding to go left and decrementing to go right from the motion vector the value of 90° / k exactly k times (let us denote this value by i) and calculate the position of the point by point.x = C.x + sin(i) * r and point.y = C.y + cos(i) * r.
Sry, I don't know python.
The shortest distance from a circle to a line is the shortest distance from its center to that line, minus the radius of the circle. If the distance from the center to the line is less than the radius, the line passes through the circle.
Finding the distance from a point to a line is documented many places, including here.
Sorry for not posting Python code, but it is pretty basic.
I would like to convert a point coordinates to a new generated coordinate system
the original system start in the top left corner of the image (0,0)
The information that I have in a new system are :
1- I have the value of the new original (x0,y0) in some where in the image
2- also I have 2 points on both new axes ( 4 points in total 2 in each line)
using this I can calculate the line equation for the 2 lines of axes (y=a1x+b1) ,(y=a2x+b2)
3- I have vector for each line (Vx, Vy)
Note: sometime the new axes rotate (the lines are not exactly horizontal or vertical)
How can I convert the points coordinates to this new system
any help will be so appreciated
here is the image
First express your lines like a1*(x-x0)+b1*(y-y0)=0 and a2*(x-x0)+b2*(y-y0)=0 and their intersection x0,y0 is accounted for already in the equations.
updated signs
The transformation from x,y to z,w is
z = -sqrt(a1^2+b1^2)*(a2*(x-x0)+b2*(y-y0))/(a2*b1-a1*b2)
w = sqrt(a2^2+b2^2)*(a1*(x-x0)+b1*(y-y0))/(a1*b2-a2*b1)
and the inverse
x = x0 - b1*z/sqrt(a1^2+b1^2) + b2*w/sqrt(a2^2+b2^2)
y = y0 + a1*z/sqrt(a1^2+b1^2) - a2*w/sqrt(a2^2+b2^2)
It would be helpful to scale the coefficients such that sqrt(a1^2+b1^2)=1 and sqrt(a2^2+b2^2)=1.
Note that this works for non-orthogonal lines also. As long as they are not parallel and a2*b1-a1*b2!=0 it is going to work.
Example
The z line (-2)*(x-3) + (1)*(y-1) = 0 and w line (-1)*(x-3) + (-4)*(y-1) = 0 meet at (3,1). The coefficients are thus a1=-2, b1=1, a2=-1, b2=-4.
The coordinates (x,y)=(2,1) transform to
z = -sqrt((-2)^2+1^2) ((-1) (x-3)+(-4) (y-1))/((-1) 1-(-2) (-4)) = 0.2484
w = sqrt((-1)^2+(-4)^2) ((-2) (x-3)+1 (y-1))/((-2) (-4)-(-1) 1) = 0.9162
With the inverse
x = -1 z/sqrt((-2)^2+1^2)+(-4) w/sqrt((-1)^2+(-4)^2)+3 = 2
y = (-2) z/sqrt((-2)^2+1^2)-(-1) w/sqrt((-1)^2+(-4)^2)+1 = 1
Development
For a line a1*(x-x0)+b1*(y-y0)=0 the direction vector along the line is e1 = [e1x,e1y]= [-b1/sqrt(a1^2+b1^2),a1/sqrt(a1^2+b1^2)]. Similarly for the other line.
The screen coordinates of a local point [z,w] is found by starting at the origin x0, y0 and moving by z along the first line and then by w along the second line. So
x = x0 + e1x*z + e2x*w = x0 -b1/sqrt(a1^2+b1^2)*z - b2/sqrt(a2^2+b2^2)*w
y = y0 + e1y*z + e2y*w = y0 +a1/sqrt(a1^2+b1^2)*z + a2/sqrt(a2^2+b2^2)*w
Now I need to flip the direction of the second line to make it work per the original posting visualization, by reversing the sign of w.
To find z, w from x, y invert the above two equations.
I am given 2 points inside a circle. I have to find a point on the circle (not inside, not outside) so that the sum of the distances between the given 2 points and the point i found is minimum. I only have to find the minimum distance, not the position of the point.
It is a minimization problem:
minimize sqrt((x1-x0)^2 + (y1-y0)^2) + sqrt((x2-x0)^2 + (y2-y0)^2)
^ ^
(distance from point1) (distance from point 2)
subject to constraints:
x1 = C1
y1 = C2
x2 = C3
x4 = C4
x0^2 + y0^2 = r^2
(assuming the coordinates are already aligned to the center of the circle as (0,0)).
(C1,C2,C3,C4,r) are given constants, just need to assign them.
After assigning x1,y1,x2,y2 - you are given a minimization problem with 2 variables (x0,y0) and a constraint. The minimization problem can be solved using lagrange multiplier.
Let (x1, y1) and (x2, y2) be the points inside the circle, (x, y) be the point on the circle, r be the radius of the circle.
Your problem reduces to a Lagrange conditional extremum problem, namely:
extremum function:
f(x, y) = sqrt((x-x1)^2 + (y-y1)^2) + sqrt((x-x2)^2 + (y-y2)^2)
condition:
g(x, y) = x^2 + y^2 = r^2 (1)
Introduce an auxiliary function(reference):
Λ(x, y, λ) = f(x, y) + λ(g(x, y) - r^2)
Let ∂Λ / ∂x = 0, we have:
(x-x1)/sqrt((x-x1)^2 + (y-y1)^2) + (x-x2)/sqrt((x-x2)^2 + (y-y2)^2) + 2λx = 0 (2)
Let ∂Λ / ∂y = 0, we have:
(y-y1)/sqrt((x-x1)^2 + (y-y1)^2) + (y-y2)/sqrt((x-x2)^2 + (y-y2)^2) + 2λy = 0 (3)
Now we have 3 variables(i.e. x, y and λ) and 3 equations(i.e. (1), (2) and (3)), so it's solvable.
Please be noted that there should be two solutions(unless two inside points happen to be the center of the circle). One is the minimal value(which is what you need), the other is the maximal value(which will be ignored).
just another approach(which is more directly):
for simplicity, assume the circle is at (0,0) with radius r
and suppose two points are P1(x1,y1) and P2(x2,y2)
we can calculate the polar angle of these two points, suppose they are alpha1 and alpha2
obviously, the point which is on the circle and having the minimum sum of distance to P1 and P2 is within the circular sector composed of alpha1 and alpha2
meanwhile, the sum of distance between the point on the circle within that sector and P1 and P2 is a quadratic function. so, the minimum distance can be found by using trichotomy.
I have some damaged line segments in a binary image and I need to fix them (make them straight and at their original thick). In order to do that I have to find the middle points of the segment, so when I check the neighborhood to find the thickness of the lines I'll be able to find where the pixel stops being 1 and becomes 0.
Assuming your damaged line segments are straight, you can use regionprops in MATLAB to find the center of each bounding box. Because if a segment is straight, its is always the diagonal line of the bounding box, thus the center of the box is also the center of the semgent.
Let's call the points A and B to reduce ambiguity, A(Xa, Ya) and B(Xb, Yb)
Let C be the middle point.
C(Xc, Yc)
Xc = (Xa + Xb) / 2
Yc = (Ya + Yb) / 2
We have four interesting numbers, two for the X coordinates and two for the Y coordinates.
Xmin = floor(Xc)
Xmax = ceil(Xc)
Ymin = floor(Yc)
Ymax = ceil(Yc)
The X coordinate of your middle point is either Xmin or Xmax, the Y coordinate of your middle point is either Ymin or Ymax.
So we have four potential points: (Xmin, Ymin), (Xmin, Ymax), (Xmax, Ymin), (Xmax, Ymax).
So, finally, we must decide which point is nearest to C.
Distance from P(Xp, Yp) to C(Xc, Yc) is:
sqrt(sqr(Xp - Xc) + sqr(Yp - Yc))
Calculate the four distance from the four points to C, choose the minimum and that will be the best possible middle point.
Suppose
A = [xa ya];
B = [xb yb];
then
C = round( mean([A;B]) );
Matlab's round rounds numbers towards their nearest integer, so this minimizes the (city-block) distance from the analytical center (mean([A;B])) to the nearest pixel.
If you want to keep sub-pixel precision (which is actually advisable for most calculations until an explicit map from a result to pixel indices is required), just drop the round and use only the mean part.