implicit-0.0.2: Graphics/Implicit/ObjectUtil/GetBox2.hs
-- Implicit CAD. Copyright (C) 2011, Christopher Olah (chris@colah.ca)
-- Released under the GNU GPL, see LICENSE
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, TypeSynonymInstances, UndecidableInstances #-}
module Graphics.Implicit.ObjectUtil.GetBox2 (getBox2) where
import Prelude hiding ((+),(-),(*),(/))
import qualified Prelude as P
import Graphics.Implicit.SaneOperators
import Graphics.Implicit.Definitions
import qualified Graphics.Implicit.MathUtil as MathUtil
import Data.List (nub)
getBox2 :: SymbolicObj2 -> Box2
-- Primitives
getBox2 (RectR r a b) = (a,b)
getBox2 (Circle r ) = ((-r, -r), (r,r))
getBox2 (PolygonR r points) = ((minimum xs, minimum ys), (maximum xs, maximum ys))
where (xs, ys) = unzip points
-- (Rounded) CSG
getBox2 (Complement2 symbObj) =
((-infty, -infty), (infty, infty)) where infty = (1::ℝ)/(0 ::ℝ)
getBox2 (UnionR2 r symbObjs) =
let
boxes = map getBox2 symbObjs
isEmpty = ( == ((0,0),(0,0)) )
(leftbot, topright) = unzip $ filter (not.isEmpty) boxes
(lefts, bots) = unzip leftbot
(rights, tops) = unzip topright
left = minimum lefts
bot = minimum bots
right = maximum rights
top = maximum tops
in
((left-r,bot-r),(right+r,top+r))
getBox2 (DifferenceR2 r symbObjs) =
let
firstBox:_ = map getBox2 symbObjs
in
firstBox
getBox2 (IntersectR2 r symbObjs) =
let
boxes = map getBox2 symbObjs
(leftbot, topright) = unzip boxes
(lefts, bots) = unzip leftbot
(rights, tops) = unzip topright
left = maximum lefts
bot = maximum bots
right = minimum rights
top = minimum tops
in
((left-r,bot-r),(right+r,top+r))
-- Simple transforms
getBox2 (Translate2 v symbObj) =
let
(a,b) = getBox2 symbObj
in
if (a,b) == ((0,0),(0,0))
then ((0,0),(0,0))
else (a+v, b+v)
getBox2 (Scale2 s symbObj) =
let
(a,b) = getBox2 symbObj
in
(s ⋯* a, s ⋯* b)
getBox2 (Rotate2 θ symbObj) =
let
((x1,y1),(x2,y2)) = getBox2 symbObj
rotate (x,y) = ( cos(θ)*x - sin(θ)*y, sin(θ)*x + cos(θ)*y)
(xa, ya) = rotate (x1, y1)
(xb, yb) = rotate (x1, y2)
(xc, yc) = rotate (x2, y1)
(xd, yd) = rotate (x2, y2)
minx = minimum [xa, xb, xc, xd]
miny = minimum [ya, yb, yc, yd]
maxx = maximum [xa, xb, xc, xd]
maxy = maximum [ya, yb, yc, yd]
in
((minx, miny), (maxx, maxy))
-- Boundary mods
getBox2 (Shell2 w symbObj) =
let
(a,b) = getBox2 symbObj
d = w/(2.0::ℝ)
in
(a - (d,d), b + (d,d))
getBox2 (Outset2 d symbObj) =
let
(a,b) = getBox2 symbObj
in
(a - (d,d), b + (d,d))
-- Misc
getBox2 (EmbedBoxedObj2 (obj,box)) = box