I have a vector from a certain point, and its angle, there are also lines described by two points. I need to find the points of intersection of a vector with lines. I calculated the intersection, through the equation of lines, but in this case I find intersections with lines that are on the opposite side of the direction of the vector, so I decided to check if the line is in the vector's direction, but I can't think of the right condition. The screenshot shows an example of what it means when an angle is between two other angles. At the moment the angles are from -180 to 180, but I would be very grateful for a solution with angles from 0 to 360 too.
A sequence of actions to check, either mathematically or in code form would help me.
CodePudding user response:
First get the order of the endpoints right. Sort them numerically; if the difference is < 180, then this step is done, otherwise add 360 to the lesser one and reverse them.
Then see if the ray falls between them. If it is greater than the first point but less than the second, then there is an intersection; otherwise add 360 to the ray and test a second time.
Example 1: Line is from 80 to 280, ray is at 350. The difference between the endpoints is 200, which is greater than 180, so change the lesser endpoint: the line is from 280 to 440. The ray, at 350, is between these endpoints, so the ray intersects the line.
Example 2: Line is from 50 to 140, ray is at 260. The difference between the endpoints is 90, which is less than 180; no adjustment needed. The ray is not between them; add 360 to the ray to make it 620. The ray is still not between the endpoints, so the ray does not intersect the line.
This solution works for angles measured from 0 to 360. If the given angles are given from -180 to 180, just add 180 to everything first.
CodePudding user response:
Here is a solution if you have finite lines. It doesn't have the algorithm from scratch as it uses shapely, but it works. Plus, since its python, should be faster to use library anyway.
import math
import shapely.geometry.linestring
from matplotlib import pyplot as plt
from math import pi, cos, sin
from random import random
#make 2 random points inside unit circle
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return str((self.x, self.y))
class Circle:
def __init__(self, origin, radius):
self.origin = origin
self.radius = radius
origin = Point(0, 0)
radius = 1
circle = Circle(origin, radius)
vector_points=[]
for i in range(2):
p = random() * 2 * math.pi
r = circle.radius * math.sqrt(random())
vector_points.append((math.cos(p) * r,math.sin(p) * r))
#make random points on edge of unit circle
def point(h, k, r):
theta = random() * 2 * pi
return h cos(theta) * r, k sin(theta) * r
#math functions
def line_intersection(line1, line2):
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(xdiff, ydiff)
if div == 0:
raise Exception('lines do not intersect')
d = (det(*line1), det(*line2))
x = det(d, xdiff) / div
y = det(d, ydiff) / div
return x, y
if __name__ == '__main__':
#vizualize unit circle
xy = [point(0,0,1) for _ in range(3000)]
#two points on edge of unit circle, display with line
line=[point(0,0,1) for _ in range(2)]
#make vector inside unit circle, display with line
vector=vector_points
#display everything
plt.axes().set_aspect('equal')
plt.scatter(*zip(*xy), color='b')
plt.plot(*zip(*line), color='r')
plt.plot(*zip(*vector_points),color='g')
plt.show()
#check intersection of finite lines
check=shapely.geometry.linestring.LineString
line1=check(vector)
line2=check(line)
if line1.intersects(line2):
print(line_intersection(vector,line))
else:
print('lines do not intersect')