简体   繁体   English

条件是其他两个角之间的角

[英]the condition is the angle between two other angles

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.目前角度从 -180 度到 180 度,但我也非常感谢角度从 0 到 360 度的解决方案。 在此处输入图像描述

A sequence of actions to check, either mathematically or in code form would help me.要检查的一系列操作,无论是数学形式还是代码形式,都会对我有所帮助。

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.如果差值<180,则完成此步骤,否则将较小的加上360并取反。

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.否则将 360 添加到射线并进行第二次测试。

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.例1:线从80到280,射线在350。端点之间的差是200,大于180,所以改变较小的端点:线从280到440。射线,在350,是在这些端点之间,因此射线与直线相交。

Example 2: Line is from 50 to 140, ray is at 260. The difference between the endpoints is 90, which is less than 180;例2:直线从50到140,射线在260,端点相差90,小于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.向光线添加 360 使其成为 620。光线仍然不在端点之间,因此光线不与直线相交。

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.此解决方案适用于从 0 到 360 度测量的角度。如果给定的角度是从 -180 度到 180 度,只需先将所有内容加上 180 度。

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.另外,由于它是 python,无论如何使用库应该更快。

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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM