packages feed

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