How To Calculate angle between 2 lines at intersection - c#

I want to know how to calculate agnle between 2 lines at intersection point.
Please see following image. Here Red line is crossing Green line how can i calculate that angle.?

Calculate the direction vectors of both lines and normalize them:
d := (x2 - x1, y2 - y2)
length = sqrt(d.x^2 + d.y^2)
d := (d.x / length, d.y / length)
Then, you have multiple options to calculate the angle. One simple way is to use the dot product:
dot = dRed.x * dGreen.x + dRed.y * dGreen.y
angle = arc cos(dot)
If you also want to reconstruct angles greater than 180° (you will need correct line orientations then), you need the cross product:
cross = dRed.x * dGreen.y - dRed.y * dGreen.x
angle = atan2(cross, dot)

You can calculate the point of intersection of two lines (if you know the equation of the two lines). Using that point of intersection you can find another point on one of the lines and get the projection of one of the lines onto another. This projection will give you the angle between the two lines.
Also if you know the equation of one of the lines and a point on another line, you can still use this method to find out the angle between the two lines.

Related

I am trying to code Canny edge detection in C#

I am trying to code Canny edge detection in C#. I am confused about finding the Direction of the edge. I know The Direction is the angle between the gradient vector and the x-axis. When finding the gradient vector's Direction (D), you do inverse tan of the y/x ratio.
I understand that part. The part that I am lost at is some examples online seem to add PI out of nowhere, and I do not understand. So is it :
` double angle = X/ Y;
double radians = angle * (180/Math.PI);
Angle = Math.Tan(radians) + Math.PI;`
or this:
double angle = X/ Y;
double radians = angle * (180/Math.PI);
Angle = Math.Tan(radians);
I have also seen :
orientation[index] = Math.Atan2(dy, dx) + Math.PI;
but this is not even inverse tan or is it ?
Both your first examples don't make any sense. X / Y is surely not an angle but the tangens of an angle.
To get the angle from the tangens you must use the one of the two inverse functions Math.Atan or Math.Atan2.
Always prefer Math.Atan2 over Math.Atan if you have got both components (X and Y) of the direction vector because Math.Atan2 returns an unambiguous angle in the range for -Pi to +Pi, while Math.Tan only gives you a result in the range form -Pi/2 to +Pi/2. Then you have to decide if in a certain case you have to add or subtract Pi (ATan doesn't "know" whether the angle is in the first or in the third quadrant if the result is positive or whether it is in the second or fourth quadrant if the result is negative).
Try to learn how to work with trigonometric functions and when you understand how to apply them and the corresponding inverse trigonometric functions come back to your programme.
And read the Microsoft documentation concerning the trigonometric functions.

Algorithm for finding grid cells contained in arbitrary rotated rectangle (rasterizing)

I'm looking for an algorithm that can compute all grid cells occupied by an arbitrary rectangle in 2d space in a defined area. The rectangle is defined by it's 4 corner coordinates. In the picture below I marked two of them as red, the coordinates of the grid cells are in black. I'm looking for a generic case that also covers unaligned grids (center of grid != center of underlying coodinate system), but converting between Cell coordinates <=> Coordinate system is trivial and already implemented. All cells are squares.
The calculation is done thousands in very short amounts of time and needs to be as fast as possible.
What I'm doing right now:
Right now I'm calculating the edges of the rectangle (AB, BC, CD, DA) and sample them at sampleRate = cellWidth / 4 intervals. To find the middle cells I construct new lines from AB + sampleRate * x to CD + sampleRate * x and sample those lines again at sampleRate. I put all cells that I find at each sampled point into a HashSet to remove duplicates. But I feel this is increadibly inefficient.
I also thought about grabbing all cells in my relevant area into a buffer and generate a range tree or index tree. Then I could queue the bounds of the rectangle and get all contained cells at O(log n+m), but I'm not sure how to implement that and I can't even find any C# range tree implementations.
My knowledge in computer graphics is very rusty, but shouldn't there be an easy geometrical approach that works without sampling?
The points you care about are marked with a dot in the image below. Each point represents either the minimum X value or the maximum X value for a given Y value. For each Y value, the X value is easily calculated from the equation for a line:
x = x0 + (y - y0)(x1 - x0) / (y1 - y0)
Note that an axis-aligned rectangle (where (y1 - y0) is 0) needs to be handled as a special (but trivial) case.
Also note that once you've computed the first X value along an edge of the rectangle, the other X values are equally spaced. The spacing is the inverse of the slope of the line. So the division
M = (x1 - x0) / (y1 - y0)
only needs to be done once, and then repeatedly added to the X value. For example, after calculating the X coordinate for point A in the image, the X coordinate for point B is Bx = Ax + M. And the X coordinate for point C is Cx = Bx + M.
Once you have the min and max X values for each Y value, it's a simple for loop to get all the cells that have that Y value.

converting xinput coordinates to a square

i'm working on a small c# program that uses xinput to read the xbox 360 thumb stick.
i have no problem with reading the coordinates and normalizing the values so i get a float between -1 and +1 for X and Y directions.
the problem i have is that the stick itself is physically limited to a circle and in my case i would like to "stretch out" the coordinates so it becomes more of a square than a circle.
the reason is that each direction is controlling a motor and if i move the stick for example top right i would like both X and Y to become 1.
since the stick is circular this is not possible and this also makes it impossible to make both motors run at full speed.
any advice?
So you want a point on a circle of radius r to be mapped to a point on a square of radius r on the same ray through the origin. Toward that goal you have to compute the radius using the usual formula
r = sqrt(x*x+y*y)
and then from that the scale factor
f = r / max ( abs(x), abs(y) )
and in the end replace x by f*x and y by f*y.
One can vary this computation by noting that the factor is
f = sqrt ( 1 + (x*x)/(y*y) )
if abs(y) > abs(x) and
f = sqrt ( 1 + (y*y)/(x*x) )
in the opposite case. Or by noting that the largest coordinate gets replaced by r and the smaller scaled accordingly, which also does not reduce the logistics by much.

How do I remove redundant vertices from list

I have list of vertices i.e List<Point>, which contains following points for square:
(0,0),
(1,0),
(2,0),
(3,0),
(4,0),
(4,1),
(4,2),
(4,3),
(4,4),
(3,4),
(2,4),
(1,4),
(0,4),
(0,3),
(0,2),
(0,1),
(0,0)
To draw a square I just need four points (0,0), (0,4), (4,4), (4,0), how do I remove redundant (which makes straight line) points from list?
It is not always square, basically I want to reduced the number of points if they form straight line. For example (0,0), (0,1), (0,2), (0,3), (0,4) makes straight line instead of drawing all four points it would be quick to draw a line from points (0,0), (0,4).
Look at three successive points at a time (let's call them p0, p1, p2). These three points are collinear (form a single line) if p2 = p0 + k(p1 - p0) where k is an arbitrary real number. We can express the above condition in terms of simultaneous equations:
(x2 - x0) = k(x1 - x0)
(y2 - y0) = k(y1 - y0)
In theory, all you need to do is takes each set of three points in turn. Calculate the value of k for the x components and y components; if they are the same, then the lines are collinear, so delete p1.
In practice, this becomes more tricky in the general case due to the limitations of fixed-point or floating-point. Points that should be collinear may not be quite collinear once their coordinates have been quantised. So you may need to allow for some error margin when doing the comparisons.
One way to do it automatically would be to take the points containing a combination of minX, maxX, minY and maxY (that is the most spread coordinates and assuming the other points in the array are all within the rectangle bounds).
You might want to give some more details and constraints if this does not answer the question you have in mind.

Cone-Line Segment Intersection 2D

I would like to know if is there any way to determine if a cone is intersecting with a (finite) line segment. The cone is actually a circle located at P(x,y) with theta degree field of view and radius r:
I'm trying to do it in C# but I don't have any idea how to that, so for now this is what I'm doing:
Check if the line segment is intersecting with the circle;
If the line segment is intersecting with the circle then I check every single point in the line segment using a function I found here.
But I don't think this is the best way to do it. Does anyone have an idea?
For additional info, I need this function to make some kind of simple vision simulator.
Working with Polar Co-ordinates might help. Here, instead of representing a point as (x,y) you represent it as (r, angle), where r is distance from origin and angle is the angle made with a chosen axis (which corresponds to angle 0).
In your case, if you set P(x,y) to be origin and one of the rays of the cone as angle = 0 and find polar co-ordinates of the end points of the line segment, say (r1, ang1) and (r2, ang2) then you need the following four conditions to be true for the line segment to be completely within (including boundary) of the cone.
r1 <= r
r2 <= r
ang1 <= theta
ang2 <= theta
where r is the radius of the cone and theta is the angle of view and you chose the axis so that rotating counter-clockwise gives a corresponding positive angle.
Switching between polar and (x,y) (called rectangular) coordinates is easy, and you can find it on the wiki link I gave above.
In order to determine if any point of the line segment intersects the curve you can use the polar equation of a line give here: Link
We can use the Polar normal form
R = p sec(ang - omega)
We can figure out p and omega given the two end-points of the line segment as follows:
We have
p = r1 * cos(ang1-omega) = r2*cos(ang2-omega)
Using cos(x-y) = cos(x)*cos(y) + sin(x)*sin(y) we get
[r1*cos(ang1) - r2*cos(ang2)] * cos(omega) = [r2*sin(ang2) - r1*sin(ang1)] * sin(omega)
Thus you can calculate tan(omega) = sin(omega)/cos(omega) and use arctan (the inverse function of tan) to get the value of omega. Once you know what omega is, you can solve for p.
Now we need to know if there is some (R, ang) combination on this line such that
R <= r
0 <= ang <= theta
min{ang1, ang2} <= ang <= max{ang1, ang2}
(Note r was radius of cone, and theta was the angle of view, ang1 was angle of P1 and ang2 was angle of P2).
The equation can be rewritten as
Rcos(ang-omega) = p
Now cos(ang-omega) is a very nicely behaved function in terms of monotonicity and you only need to consider it in the interval [min{ang1, ang2}, max{ang1, ang2}].
You should be able to do some manual manipulations first in order to simplify your code.
I will leave the rest to you.
I'd Google around for line/convex polygon intersection algorithms, your field of view is composed of a triangle and a part of a circle which can be approximated to any degree of accuracy by a convex polygon. Your first step might still be useful to rule out lines which go nowhere near the field of view.
If you keep it 2D like above, intersection can be calculated as follows:
Starting point of line segment is S1, ending is S2.
Left edge of code is a vector along the edge C1, right edge is C2, Origin of code is O.
Take the sign of the Z component of the cross product of the vector formed from (O to S1) and C1.
Take the sign of the Z component of the cross product of the vector fromed from (O to S2) and C1. If the signs differ, your starting and ending points are on opposite sides of C1 and therefore they must intersect. If not, do the same comparisons with C2 instead of C1.
If neither side's signs differ, no edge intersection.
In 3D, it's a bit more complicated. I've googled and found cone sphere intersection any number of times. Doing it for lines, would be very similiar, I just need to think about it for a bit :)
A quick google of 'cone line intersection' got all sorts of hits. The basic idea is to form a plane from the cone's origin and the starting and ending point of the line. Once you have that, you can take the angle between that plane and the cone's direction normal. If that angle is less than the angle of the spread on the cone, you have an intersection.

Categories

Resources