python-3.x 我有射线类和线类,想找到线-射线交点

bvjveswy  于 2023-02-14  发布在  Python
关注(0)|答案(1)|浏览(138)

我为Ray、Line、Point和其他一些形状编写了类,但我被一个函数的需要所阻止,该函数将Line类对象和Ray类对象作为参数,并返回直线和射线相交的点。
点类:

class Point:
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y

    def __getitem__(self, index):
        if index == 0:
            return self.x

        elif index == 1:
            return self.y

    def __iter__(self):
        yield self.x
        yield self.y

    def __str__(self):
        return f"x = {self.x}; y = {self.y}"

射线等级:

class Ray:
    def __init__(self, start: Point, end: Point):
        self.start = start
        self.end = end
        
    def get_direction(self):
        x_diff = self.end[0] - self.start[0]
        y_diff = self.end[1] - self.start[1]
        return (x_diff, y_diff)

线路等级:

class Line:
    def __init__(self, point1: Point, point2: Point):
        self.point1 = point1
        self.point2 = point2

    def get_direction(self) -> tuple:
        x_diff = abs(self.point2[0] - self.point1[0])
        y_diff = abs(self.point2[1] - self.point1[1])
        return (x_diff, y_diff)
        
    def get_params(self) -> tuple:
        x1, y1 = self.point1
        x2, y2 = self.point2
        
        a = y2 - y1
        b = x1 - x2
        c = x2 * y1 - x1 * y2
        
        return a, b, c
    
    def get_normal(self):
        a, b, c = self.get_params()
        return -b, a, c

以下函数可能会有所帮助:点在线上吗?

def point_on_line(point: Point, line: Line):
        x1, y1 = line.point1
        x2, y2 = line.point2
        x, y = point

        return (y - y1) * (x2 - x1) == (y2 - y1) * (x - x1)

点在射线上吗?

def point_on_ray(point: Point, ray: Ray) -> bool:
    start = ray.start
    end = ray.end
    direction = ray.get_direction()

    x_diff = point[0] - start[0]
    y_diff = point[1] - start[1]

    if x_diff * direction[1] == y_diff * direction[0]:
        if x_diff >= 0 and y_diff >= 0:
            return True

    return False

我数学不好,所以我请ChatGPT来帮我,但是他写了一些函数,会返回错误的结果
我试着给ChatGPT几个完全不同的提示,得到了几个完全不同的函数作为响应,但无论如何,它们都不起作用。其中一些函数返回了错误的点,一些函数认为射线和直线是平行的,尽管它们没有正确地工作

gblwokeq

gblwokeq1#

你要解方程组

ray.start.x + t * ray.diff.x = line.point1.x + u * line.diff.x
ray.start.y + t * ray.diff.y = line.point1.y + u * line.diff.y

对于未知数tu,则检查t >= 0
然后将t值代入左边部分,得到交点坐标。
独立Python函数

def ray_line_intersection(rx0, ry0, rdiffx, rdiffy, lx0, ly0, ldiffx, ldiffy):
    denom = ldiffy * rdiffx - ldiffx * rdiffy

    if denom == 0:    #ray and line are parallel or coincident
        return (1) if (lx0 - rx0) * rdiffy == (ly0 - ry0) * rdiffx else None

    t = (ldiffx * (ry0 - ly0) + ldiffy * (lx0 - rx0)) / denom
    return (rx0 + rdiffx * t, ry0 + rdiffy * t) if t >=0 else None

print(ray_line_intersection(0, 0, 1, 1, 3, 0, -1, 1))
print(ray_line_intersection(0, 0, 1, 1, 3, 0, 1, 1))
print(ray_line_intersection(0, 0, 1, 1, -1, -1, 4, 4))
print(ray_line_intersection(0, 0, 1, 1, -1, 0, 1, -1))

>>> (1.5, 1.5) normal intersection
>>> None   parallel
>>> 1      ray lies  in the line 
>>> None  intersection beyond ray range

相关问题