How to detect Line segment intersection with Cylinder? [duplicate] - algorithm

This question already has answers here:
Trying to optimize line vs cylinder intersection
(4 answers)
Closed 7 years ago.
Say we have a 3d space, Line segment defined by its start and end points (A {Ax, Ay, Az}, B {Bx, By, Bz}) and cylinder defined by its center position C {Cx, Cy, Cz}, radius R and height H. How to get a fact of intersection and if intersection happened than where?

Try this. Google for the win - the answer is even here on SO. This even has source code and links to more information for you to use. With just a little bit of searching, you could have got this yourself.
This is based on #DuckQueen's answer - it just adds projecting the intersection point - if any - to see if it falls within the height of the cylinder.

Let x = (y-a2)/b2 = (z-a3)/b3 be the equation for line.
Let (x-c1)^2 + (y-c2)^2 = d^2 be the equation for the cylinder.
Substitute x from the line equation into the cylinder equation.
You can solve for y using the quadratic equation. You can have 0 solutions (cylinder and line does not intersect), 1 solution or 2 solutions.
Substitute the value of y into the line equation to get x and z coordinates.
For getting line equation from two points see: http://www.nabla.hr/Z_CGLinesAndPlanesIn3DSpace-A.htm
The solution I provided works for cylinder of infinite height. To restrict to a cylinder of height H: Find the points of intersection, if the points are within the height (i.e. z is within limits), output points.

Related

Interview: draw shapes (circles & squares) until area is less than X

I was recently asked this question at an interview and I wasn't able to solve it. I wanted to post it here and see if anyone can give me some ideas on how to approach on solving such problems.
Question: Given positive X axis and Y axis...
Start by drawing a square of width=A (say A=1000)
Next draw a circle of maximum possible radius inside the square such that the circle touches all 4 sides of the square.
Next draw a square inside this circle such that all 4 vertices of the square are touching the circle.
Keep repeating the above process and keep drawing circles and squares alternatively until the area of the shape just drawn is < B (say B=10).
Write the pseudocode/logic to achive this.
Here is a sample diagram showing what the interviewer asked (excuse the mishapen portion).
You have 2 cases:
You're given width of a square the circle's area would then be
A = (width^2)*pi/4
You're given radius of a circle the square's area would then be
A = 2*(R^2)
In python:
R=0
width=1000
result=1000000
B=10
square=True
while result > B:
if square:
R=width/2
result=math.pi*(R*R)
else:
width=R*math.sqrt(2)
result=2*R*R
square = not square
print(result)
This is quite a simple math problem. The basic idea is to always calculate the surface by knowing the square's side and the circle's diameter (or radius). The formulas are:
P = a^2 for the square
P = (D^2)/4 for the circle where D is the diameter (not radius).
The side of the first square is a, then this means that the diameter of the next circle is also a, which in turn means that the diagonal of the next square is a. You can use Pythagorean theorem to calculate the side of the square and you repeat this until you reach the surface which is less than the one required.
I've not written a single line of code because the language is not specified and I think you can manage that with my idea. And on those interviews, they usually just want to see your line of thinking.

Voronoi Diagram: How to implement parabloas?

I've been trying to implement a Voronoi Diagram using Fortunes Algorithm. I understand how it works but I'm stuck at how to store the parabolic arcs.
I understand all this is needed for the parabola is the sweeplines' Y position and the sites position but I'm I don't understand what to do with it.
I found this equation online (via this site):
What is X in this equation?
I'd say that y = ax2 + bx + c is the equation of a parabola with vertical axis. In this case, a,b,c are given in more detail. ly is a parameter which describes the current position of the sweep line and therefore influences the shape of the parabola. So your equation describes a whole family of parabolas, with pj,x and pj,y being the coordinates of the point you actually store in your data structure.

Point on a line closest to x,y [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I tell if a point is nearby a certain line?
//Returns the point on the line traced from start to end which
//comes nearest to 500,000, 500,000. The points are scaled between
//1,000,000 and 0 from their original fp types.
Point closestToCentre(Point start, Point end);
Anyone know of quicker way than single stepping through the pixels?
Could some one more alert than me demonstrate their maths & geometry prowess please?
_______EDIT___________
Thanks Kris, this was confusing me :
[x; -a/bx-c/b]=[0; -c/b]-1/b[-b; a]x.
Now I see it is just splitting (mainly the y component) the vector into two which combine to yield the same result. Got the old partial fractions brain cell excited for a minute then :)
_______EDIT_________
Jason Moore, thanks for the inspiration, here is what I am doing, graphically,
I hope that is clearer.
____EDIT________
So I could reasonably expect to take a line at right angles to my sampled line and run it from the centre but how to tell when they touch?
I think Kris's page of equations is the way to go. If you're all telling me it is a two step process. It is just two simultaneous equations now, so I may not need Kris's derivations.
____EDIT_________
Whether good or bad thing, I don't know, but the beauty of stackoverflow as a search engine has revealed to me several routes of investigation. Chiefly I like the first solution here:
Shortest distance between a point and a line segment.
But to prove this to my self I needed the link from matti's solution at the bottom (but one):
http://www.topcoder.com/tc?d1=tutorials&d2=geometry1&module=Static
The derivation is so simple and elegant even I could follow it!
Given http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
This is a matter of linear projection of a point onto a line, which can be done with some fine vector gymnastics, as elaborated at MathWorld.
The article details how to find the shortest distance from a point to a line, and one of the intermediate steps is finding the perpendicular line from the point x,y to the original line. Intersecting these two lines will give you the point, on the line, closest to x,y.
Edit in response to comment: What equation (2) in the link is doing is transforming the vector into a form reminiscent of y = mx + c, which allows you to quickly and easily read off the gradient, from which the perpendicular gradient can be easily calculated.
I think the quickest way will be a two step process:
Assume your line is infinite in length, and find the intersection of your line and its perpendicular bisector through (500,000, 500,000).
Make sure that point is actually on your line, else find the closest endpoint.
Kris's post covers step 1 pretty well, all you have to do is add the check for step 2 because you have a line segment and you're golden.
Let point 1 = (x1, y1) and endpoint 2 = (x2, y2). Then the line containing these two points is
y = (y2 - y1)/(x2 - x1) * (x - x1) + y1
and the perp. bisector through (5e5, 5e5) is
y = (x1 - x2)/(y1 - y2) * (x - 5e5) + 5e5
Your point (x,y) is the solution (x,y) to the above two equations (or one of the two endpoints). This might be more straightforward than the mathworld link. Note that this solution fails, however, when your line is either almost vertical or almost horizontal whereas I don't think the mathworld solution style does, though I haven't looked very closely.

How can I inscribe a rectangle or circle inside an arbitrary quadrilateral

This may be a more math focused question, but wanted to ask here because it is in a CS context. I'm looking to inscribe a rectangle inside another (arbitrary) quad with the inscribed quad having the largest height and width possible. Since I think the algorithm will be similar, I'm looking to see if I can do this with a circle as well.
To be more clear hear is what I mean by the bounding quadrilateral as an example.
Here are 2 examples of the inscribed maximization I'm trying to achieve:
I have done some preliminary searching but have not found anything definitive. It seems that some form of dynamic programming could be the solution. It seems that this should be a linear optimization problem that should be more common than I have found, and perhaps I'm searching for the wrong terms.
Notes: For the inscribed square assume that we know a target w/h ratio we are looking for (e.g. 4:3). For the quad, assume that the sides will not cross and that it will be concave (if that simplifies the calculation).
1) Circle.
For a triangle, this is a standard math question from school program.
For quadrilateral, you can notice that maximum inner circle will touch at least three of its sides. So, take every combination of three sides and solve the problem for each triangle.
A case of parallel sides have to be considered separately (since they don't form a triangle), but it's not terribly difficult.
2) Rectangle.
You can't have "largest height and width", you need to choose another criteria. E.g., on your picture I can increase width by reducing height and vice versa.
4 year old thread, but I happened to stumble accross it when googling my problem.
I have a problem like this in a current CV application. I came up with a simple and somewhat clumsy solution for the finding the largest. Not exactly the same though, cause I maximize the area of the rectangle without a fixed ratio of sides.
I don't know yet wether my solutions finds the optimum or whether it works in all cases. I also think there should be a more efficient way, so I am looking forward to your input.
First, assume a set of 4 points forming our (convex) quadrilateral:
x y
P1 -2 -5
P2 1 7
P3 4 5
P4 3 -2
For this procedure the leftmost point is P1, the following points are numbered clockwise. It looks like this:
We then create the linear functions between the Points. For each function we have to know the slope k and the distance from 0: d.
k is simply the difference in Y of the two points divided by the difference in X.
d can be calculated by solving the linear function to d. So we have
k=dy/dx
d=y1-k*x1
We will also want the inverse functions.
k_inv = 1/k
d_inv = -d/k
We then create the function and inverse function for each side of the quadrilateral
k d k d
p1p2 4 3 p1p2_inv 0.25 -0.75
p2p3 -0.67 7.67 p2p3_inv -1.5 11.5
p3p4 7 -23 p3p4_inv 0.14 3.29
p4p1 0.6 -3.8 p4p1_inv 1.67 6.33
If we had completely horizontal or vertical lines we would end up with a DIV/0 in one of the functions or inverse functions, thus we would need to handle this case separately.
Now we go through all corners that are enclosed by two functions that have a k with a slope with a different sign. In our case that would be P2 and P3.
We start at P2 and iterate through the y values between P2 and the higher one of P1 and P3 with an appropriate step size and use the inverse functions to calculate the distance between the functions in horizontal direction. This would give us one side of the rectangle
a=p2p3_inv(y)-p1p2_inv(y)
At the two x values x = p2p3_inv(y) and x = p1p2_inv(y) we then calculate the difference in y to the two opposite functions and take the distance to our current y position as a candidate for the second side of our rectangle.
b_candidate_1 = y-p4p1(p2p3_inv(y))
b_candidate_2 = y-p4p1(p1p2_inv(y))
b_candidate_3 = y-P3p4(p2p3_inv(y))
b_candidate_4 = y-P3p4(p1p2_inv(y))
The lesser of the four parameters would be the solution for side b.
The area obviously becomes a*b.
I did a quick example in excel to demonstrate:
the minimum b here is 6.9, so the upper right corner of the solution is on p2p3 and the rectangle extends a in horizontal and b in vertical direction to the left and bottom respectively.
The four points of the rectangle are thus
Rect x y
R1 0.65 -1.3
R2 0.65 5.6
R3 3.1 5.6
R4 3.1 -1.3
I will have to put this into C++ code and will run a few tests to see if the solution generalizes or if this was just "luck".
I think it should also be possible to substitute a and b in A=a*b by the functions and put it into one linear formula that has to be maximized under the condition that p1p2 is only defined between P1 and P2 etc...

Computing an angle from x,y coordinates [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Circle line collision detection
I'm trying to do collision testing between a finite line segment, and an arc segment. I have a collision test which does line segment vs. line segment, so I was going to approximate these arc segments with line segments and run my existing test.
The data I have defining the arc segment(s) are three points. Two of which are endpoints that lie on the circumference of a circle, and the third point is the center of that circle.
So far this is what I've got:
Let (a,b) be the center point of the circle, let 'r' be the radius of the circle, and (x1, y1), (x2, y2) be the endpoints of the arc segment which lies on the circumference of the circle.
The following parametric equations give the x, and y locations of an arc. 't' is the parametric variable.
x = a + r * cos(t)
y = b + r * sin(t)
To create the line segments from the arc, I wanted to walk the arc for some fixed ratio of 't' creating line segments along the way, until I've reached the end of the arc. To do this I figured I'd have to find the start and end angle. I'd start walking the arc from the start angle, and end at the end angle. Since I know the start and end points I figured I could use these equations to solve for these angles. The following are my equations for this:
t = arccos((x-a)/r)
or
t = acrcsin((y-b)/r)
The problem I'm having is that the range of values returned by these functions (http://en.wikipedia.org/wiki/Inverse_trigonometric_function) is limited, so there is a high probability that the angle I'm looking for will not be returned because these functions are multivalued: arcsin(0) = 0, but also arcsin(0) = π, arcsin(0) = 2π, etc
How do I get the exact angle(s) I'm looking for? Or, can you think of a better/different way of achieving my goal?
Take a look at the atan2 function, which should exist in whatever programming language or math library you're using. It takes two arguments, the x and y coordinates of a point (for you: (x-a)/r and (y-b)/r) and returns the angle in the range -π to +π.
At least IMO, you're going at this the wrong way. A line has an equation y=mx+b. A circle has an equation x2 + y2 = r2. You're looking for a point at which the x and y of the circle equals the x and y of the line. You can do that by substituting the mx+b equation for the line for the y equation in the circle, and then solve using the quadratic equation.
The equations involved do get a bit long, but quite a few web pages (e.g., http://www.sonoma.edu/users/w/wilsonst/papers/geometry/circles/default.html) have them, at which point it's simple matter of implementing the equations as a couple of functions and plugging in the values for your particular circle/line. A solution based on these equations complete avoids the ambiguity from using an arg tangent.
Your pseudo-code looks a lot like Python. If you don't mind using Python I would recommend the Shapely Library. If you just want the algorithm, check the source.
Shapely objects have the 'simplify' and 'intersection' methods.

Resources