2

我正在寻找一种合适的方法来计算三角形的矩形边界框,该三角形具有三个角作为点 - (x1,y1)、(x2,y2)、(x3,y3)。

这是我正在使用的数据类型(按照建议,我添加了更多构造函数):

data Shape =
     Circle Point Double |
     Rectangle Point Point |
     Triangle Point Point Point

边界框函数的形式应该是“bounding :: Shape -> Shape”。我还尝试了矩形和圆形的边界框:

bounding :: Shape -> Shape
bounding (Rectangle (Point x y) (Point z z1)) = (Rectangle (Point x y) (Point z z1))
bounding (Circle (Point p w) r) = (Rectangle (Point (p-r) (w-r)) (Point (p+r) (w+r)))

如果应该使用图形坐标系(其中(x,y)坐标应该被视为(x,-y)),这些是否正确?

有人可以帮帮我吗?PS 不需要图形库。

4

3 回答 3

1

I'm only posting this answer to make the point that bounding boxes and rectangles are not the same things.

data Point = Point Double Double   -- Point x y

data BoundingBox = BoundingBox Double Double Double Double
                            -- top    left   bottom right

data Shape
    = Circle Point Double
    | Rectangle Point Point Double
        -- yes, you need two points and a scalar to specify arbitrary rectangles
    | Triangle Point Point Point

boundingBox :: Shape -> BoundingBox
boundingBox (Circle (Point x y) r) = BoundingBox (y-r) (x-r) (y+r) (x+r)
boundingBox (Rectangle (Point x0 y0) (Point x1 y1) d)
        = BoundingBox (minimum ys) (minimum xs) (maximum ys) (maximum xs) where
    xs = [x0, x1, x1+dx, x0+dx]
    ys = [y0, y1, y1+dy, y0+dy]
    d' = d / ((x0-x1)^^2 + ((y0-y1)^^2)
    dx = d' * (y0-y1)
    dy = d' * (x1-x0)
boundingBox (Triangle (Point x0 y0) (Point x1 y1) (Point x2 y2))
        = BoundingBox (minimum ys) (minimum xs) (maximum ys) (maximum xs) where
    xs = [x0, x1, x2]
    ys = [y0, y1, y2]

As an exercise, factor out the common code from the Rectangle and Triangle cases. (Bonus points for finding and fixing any bugs I've placed in the Rectangle case.)

于 2013-03-22T20:48:18.247 回答
1

基于@dave4420 的出色观察,我假设它Rectangles与 x/y 轴对齐。

根据您对 的规则Circle,看起来 x,y 最小的点排在第一位,而 x,y 最大的点在 中排在第二位Rectangle

您可能应该坚持使用数字后缀,xy不是发明新名称,例如, pw这些名称非常令人困惑。zz1

a 的边界框Rectangle就是它Rectangle本身。

a 的边界框将TriangleRectangle从任意点开始具有最小和最大 x,y 的 a。

bounding :: Shape -> Shape
bounding rect@(Rectangle _ _) = rect
bounding (Circle (Point x y) r) = Rectangle p1 p2 where
  p1 = (Point (x-r) (y-r))
  p2 = (Point (x+r) (y+r))
bounding (Triangle (Point x1 y1) (Point x2 y2) (Point x3 y3)) = Rectangle p1 p2 where
  p1 = Point (minimum [x1 x2 x3]) (minimum [y1 y2 y3])
  p2 = Point (maximum [x1 x2 x3]) (maximum [y1 y2 y3])
于 2013-03-22T20:33:18.710 回答
1

你试过什么?你有代码吗?

你需要:

 data Shape = Triangle Point Point Point | Rectangle Point Point

假设x向右增加,y向上增加。左上角是 (min{x1, x2, x3}, max{y1, y2, y3}) 并且你需要右下角。


编辑

x 应该向右增加,y 向下增加。我添加了三角形一,删除了不必要的括号并派生(显示)以便能够打印形状数据类型。给你的完整代码:

data Point = Point Double Double deriving (Show)

data Shape =
        Circle Point Double |
        Rectangle Point Point |
        Triangle Point Point Point deriving (Show)

bounding :: Shape -> Shape
bounding (Rectangle (Point x y) (Point z z1)) = Rectangle (Point x y) (Point z z1)
bounding (Circle (Point p w) r) = Rectangle (Point (p-r) (w-r)) (Point (p+r) (w+r))
bounding (Triangle (Point x1 y1) (Point x2 y2) (Point x3 y3)) = Rectangle 
        (Point (minimum [x1, x2, x3]) (minimum [y1, y2, y3])) 
        (Point (maximum [x1, x2, x3]) (maximum [y1, y2, y3]))
于 2013-03-22T19:24:01.850 回答