二维构造几何Python

2024-09-29 22:18:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试建立一个简单的二维构造几何脚本,但遇到了一些问题。我使用python中的单元测试来测试我的一些代码,但是遇到了错误,并且想知道我做错了什么。在

1)假设类“并集”确定一个点是在“left”还是“right”节点内(这可以是任意的,因为我有许多其他形状函数是基于类QuadraticSurface的),但是为了简单起见,我在代码中保留了圆定义,因为它是在单元测试中实现的。对于单元测试,它创建两个节点,L和R,如前所述,但在本例中,它是两个以原点为中心的圆,一个半径为1,另一个半径为2。对于这个特定的例子,它将分为三个点((0,0),(2,0),(1.5,0))。我已经经历了很多次迭代,都失败了,给我假不是真,反之亦然,特别是对于点(0,0)和(1.5,0)。基本上,在单元测试中,它断言两个圆形成一个环,并且环空间内外的任何东西都是真的,如果环空间中的任何东西本身都是假的,也就是点(1.5,0)。这是我自己从单元测试中收集到的,我可能是错的,我对上面的部分进行了编码,测试文件是给我的。在

2)如果点同时位于左节点和右节点中,则包含的类“交集”应返回true。我试过使用逻辑“和”,但没有成功。在

3)“QuadraticSurface”没有为光线定义交集函数,我对如何找到任意形状的交点有点迷茫。但是,当单元测试运行时,它通过一条射线,并且在x=3处通过一个垂直平面,因此对于它通过的射线,交叉点最终应该是(3,3)。在

4)有用说明基元类表示终端节点(曲面)。运算符类表示两个节点的组合。运算符的类不应实现其contains函数,但是要使用interferences函数。在

更新:我尝试了Prune建议的方法,但没有成功。对于点(1.5,0),单元测试返回AssertionError:True不是false。对于包含(p)的交点,点(1.5,0)的“假”不是真的。在

基本代码

import numpy as np
import unittest

class Point(object) :

    def __init__(self, x, y) :
        self.x, self.y = x, y       
    def __add__(self,other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x,y)  
    def __mul__(self,scale):
        x = self.x * scale
        y = self.y * scale
        return Point(x,y) 
    def __str__(self) :
        return "Point(%.6F, %.6f) " % (self.x, self.y)

class Ray(object) :  
    def __init__(self, origin, direction) :
        self.origin = origin
        norm = np.sqrt(direction.x**2 + direction.y**2)
        self.direction = Point(direction.x/norm, direction.y/norm)
    def __str__(self) :
        return "Ray: r_0(%10.6f, %10.6f), d(%.6f %.6f) " % \
           (self.origin.x, self.origin.y, self.direction.x, self.direction.y)

class Node(object) :

    def contains(self, p) :
        raise NotImplementedError

    def intersections(self, r) :
        raise NotImplementedError

class Primitive(Node) :

    def __init__(self, surface, sense) :
        self.surface, self.sense = surface, sense

    def contains(self, p) :
        return (self.surface.f(p) < 0) == self.sense

    def intersections(self, r) :
        return self.surface.intersections(r)

class Operator(Node) :

    def __init__(self, L, R) :
        self.L, self.R = L, R

    def contains(self, p) :
        raise NotImplementedError

    def intersections(self, r) :
        # get intersections with left and right nodes
        pointsL = self.L.intersections(r)
        pointsR = self.R.intersections(r)
        # return the concatenated result
        return pointsL + pointsR

class Intersection(Operator):
    def __init__(self,L,R):
        super(Intersection,self).__init__(L,R)   
        self.L = L
        self.R = R

    def contains(self,p):
        return p >= self.L and p <= self.R

    def intersections(self):
        pass            
class Union(Operator):
    def __init__(self,L,R):    
        super(Union,self).__init__(L,R)
    def contains(self,p):
        return p <= self.L or p <= self.R

class Surface(object) :

    def f(self, p) :
        raise NotImplementedError

    def intersections(self, r) :
        raise NotImplementedError

class QuadraticSurface(Surface) :

    def __init__(self, A=0.0, B=0.0, C=0.0, D=0.0, E=0.0, F=0.0) :
        super(QuadraticSurface,self).__init__()
        self.A = A
        self.B = B
        self.C = C
        self.D = D
        self.E = E
        self.F = F

    def intersections(self, r) :
        self.r = r
        x = -self.F/self.D
        y = x

    def f(self, p) :
        x = p.x
        y = p.y
        return self.A*x**2 + self.B*y**2 + self.C*x*y + self.D*x + self.E*y + self.F

class Circle(QuadraticSurface):
    def __init__(self,r,a=0.0,b=0.0):
        super(Circle,self).__init__(A=0.0,B=0.0,C=0.0,D=0.0,E=0.0,F=0.0)
        self.r = r
        self.a = a
        self.b = b
        self.A = 1.0
        self.B = 1.0
        self.C = 0.0
        self.D = -2.0*self.a**2
        self.E = -2.0*self.b**2
        self.F = self.r

单元测试

^{pr2}$

Tags: selfreturn节点initdeforigin单元测试class
1条回答
网友
1楼 · 发布于 2024-09-29 22:18:59

代码有几个问题。最直接的一点是,尽管我无法理解您的类和对象体系结构,但我可以看到包含的函数问题。以Union为例,让我们看看临界线。我在前面添加了一个print语句来查看我们比较的内容(在跟踪程序时应该这样做)。在

print p, self.L, self.R
if p <= self.L or self.R:

p是一个点;self.L和self.R是没有有用表示的原语。在

^{pr2}$

我没有看到<;=对于点和对象的定义,但它似乎是成员身份。但是,第二部分是不正确的:self.R不是布尔值。不能在“and”和“or”上分配任意操作。我想你需要的是

if p <= self.L or p <= self.R:

实际上,请注意,您只需返回这个值,就可以生成整个函数

def contains(self,p):
    return p <= self.L or p <= self.R

我希望这能解决你的问题。顺便说一句,交集函数的问题是它不返回任何内容。我建议您按照上面的代码执行相同的操作,用“and”代替“or”。在

最后,请在发布之前尝试自己调试问题:在每个问题方法的顶部添加print语句来跟踪参数值,在末尾添加print语句来报告返回值。检查失败表达式中的每个阶段。在

最重要的是,当你在这里发帖时,确保你的代码被正确地记录下来。如果我对你的工作原理有点了解的话,我可能会在最近的问题之后发现更多的问题。在


我试过用不同的点来比较函数。它们都给出了相同的表达式结果:

p <= <circle_object> returns True
p >= <circle_object> returns False

现在您已经更好地描述了代码,我可以看到问题:您没有为类定义“<;=”和“>;=”运算符。这意味着您只需比较对象控制柄;结果不会说明点是在圆内还是在圆外。在

看看你是如何在class Point中定义操作符的吗?你也需要做一些类似的事情来比较表面。在

相关问题 更多 >

    热门问题