问题描述
我最近一直在从事C ++中与计算几何相关的项目,并决定尝试编写自己的几何类/结构和函数,作为理解计算几何中事物工作方式的一种实践。
刚开始时,我用斜率和y截距表示一条直线(请记住一般公式y = mx + c
)。不久,我意识到用这种方式表示垂直线并不能真正解决问题。作为一种快速解决方案,我决定将布尔值is_vertical
和另一个字段vertical_x
(用于垂直线x轴的位置)包括在一起,而仅使用is_vertical
是真的。
虽然这种方法目前可以使用,但是当使用上述指定的2d线表示形式时,必须编写额外的代码来处理垂直条件变得非常繁琐。有没有一种更好/更好的方式来表示垂直线,或者表示计算几何中一般的线?
解决方法
有很多方法可以表示计算机几何中的线。
两种主要方法:
如评论中所述,线的一般方程为
a * x + b * y - c = 0
如果您有两个点来定义一条线,则系数为
a = (y1 - y2)
b = (x2 - x1)
c = (x2 * y1 - x1 * y2)
这种形式还可以方便地确定-某点属于线的哪一侧以及查找线点距离。
参数化方法也被广泛使用。线由基点和方向矢量定义
Base = P1
Dir = P2 - P1 (mignt be normalized to get unit length)
请注意,归一化方向矢量的分量基本上是OX和直线之间的Fi角的余弦和正弦。
可以使用参数t
X(t) = X1 + t * Dir.X
Y(t) = Y1 + t * Dir.Y
还有 Rho-Theta 定义,该定义使用较少,仅需两个标量参数即可定义任何直线-坐标原点到直线的正常距离以及OX与该直线之间的角度:
x * Sin(Theta) - y * Cos(Theta) + p = 0
,
正如Mbo在their answer中指出的那样,有几种不同的方法可以用方程式表示线。
直线的一般方程式的格式为A * x + B * y = C
。
如果您知道一条线不是垂直的,则可以使用简化的形式y = a * x + C
(从上一个等式中获得,注意B
为非零,然后让a = - A/B
)
如果您知道一条线是垂直的,则可以使用简化的格式x = c
(注意B = 0
和A
都不为零,并让c = C/A
)。 / p>
如果您知道一条线不是水平的,则可以使用简化形式x = b * y + C
。
如果您知道一条线是水平的,则可以使用简化形式y = c
。
由于可以拥有所有这些不同的表示形式,因此在面向对象的程序中处理行的一种方法是编写虚拟类Line
,然后编写几个子类GeneralEquationLine,VerticalLine,NonVerticalLine,ParametricRepresentationLine等。
大多数处理行的函数不需要知道行在内部如何表示,因此它们期望一个类Line
的对象。一些功能可能是特定于非垂直线的,因此期望使用NonVerticalLine类的对象(或者,类Line
可能具有返回true或false的方法isVertical
)。
您还可以编写函数,以在可能的情况下将子类的实例转换为另一个。