2

(x1,y1)、(x2,y2)、(x3,y3) の 3 つの角をポイントとして指定された三角形の長方形のバウンディング ボックスを計算する適切な方法を探しています。

これが私が使用しているデータ型です(提案されているように、コンストラクターを追加しました):

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

何を試しましたか?コードはありますか?

必要なもの:

 data Shape = Triangle Point Point Point | Rectangle Point Point

xが右に増加し、yが上に増加すると仮定します。左上隅は(min {x1、x2、x3}、max {y1、y2、y3})になり、右下隅が必要になります。


編集

xは右に、yは下に向かって増加するはずです。三角形1を追加し、不要な括弧を削除して、Shapeデータ型を印刷できるように派生(表示)しました。あなたのための全体のコード:

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 に答える
1

この回答を投稿して、バウンディング ボックスと四角形は同じものではないことを強調しています。

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]

Rectangle演習として、およびTriangleケースから共通コードを取り出します。(ケースに配置したバグを見つけて修正するためのボーナス ポイントRectangle。)

于 2013-03-22T20:48:18.247 に答える
1

@ dave4420 の優れた観察に基づいてRectangles、x/y 軸に沿っていると想定しています。

のルールに基づいてCircle、最小の x、y を持つポイントが最初に来て、最大の x、y を持つポイントが の 2 番目に来るように見えますRectangle

非常に紛らわしい、、などの新しい名前を発明するのではなく、数字の接尾辞xとを使用する必要があります。ypwzz1

a のバウンディング ボックスRectangleは、Rectangleそれ自体です。

a の境界ボックスは、任意の点から最小および最大の x、y を持つTrianglea になります。Rectangle

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 に答える