-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Hi,
I tried processing and it looked promising to me.
But I don't understand the generated code of the enclosed example:
The location of the vehicle is shown up correctly when done with "drawtext", but the corresponding circle is not drawn.
I did put text messages into seek.pde which showed (NaN,NaN) for the location of the vehicle...??
Regards,
Ulrich
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
-- From "The Nature of Code" by Daniel Shifman
-- http://natureofcode.com/book/chapter-6-autonomous-agents/
-- Example 6.1
import Graphics.Web.Processing.Mid
import Graphics.Web.Processing.Mid.CustomVar
import Graphics.Web.Processing.Html
import Control.Applicative ((<$>))
import Control.Monad (when)
import GHC.Generics
main :: IO ()
main = writeHtml "processing.js" "seek.pde" "Seeking a point" "seek.html" seek
--{{{ addP, subtractP, lengthP, scalarNult, setMag, limit, heading, atan22
addP :: Proc_Point -> Proc_Point -> Proc_Point
addP (x1,y1) (x2,y2) = (x1+x2, y1+y2)
subtractP :: Proc_Point -> Proc_Point -> Proc_Point
subtractP (x1,y1) (x2,y2) = (x1-x2, y1-y2)
lengthP :: Proc_Point -> Proc_Float
lengthP (x,y) = sqrt $ x_x + y_y
scalarMult :: Proc_Float -> Proc_Point -> Proc_Point
scalarMult k (x,y) = (k_x, k_y)
setMag :: Proc_Float -> Proc_Point -> Proc_Point
setMag k (x,y) =
let le = lengthP (x,y)
in (k_x/le, k_y/le)
limit :: Proc_Float -> Proc_Point -> Proc_Point
limit lim p =
if lim >= lengthP p
then p
else setMag lim p
-- answer the angle of rotation for the vector
heading :: Proc_Point -> Proc_Float
heading (x,y) = atan22 y x
atan22 :: Proc_Float -> Proc_Float -> Proc_Float
atan22 y x
| x > 0 = atan (y/x)
| x == 0 && y > 0 = pi/2
| x < 0 && y > 0 = pi + atan (y/x)
| x <= 0 && y < 0 = -atan22 (-y) x
| y == 0 && x < 0 = pi -- must be after the previous test on zero y
| x==0 && y==0 = y -- must be after the other double zero tests
| otherwise = x + y -- x or y is a NaN, return a NaN (via +)
----------------------------------------------------------------}}}
--{{{ Vehicle, newVehicle, ppshow
data Vehicle = Vehicle
{ location, velocity, acceleration :: Proc_Point
, r, maxforce, maxspeed :: Proc_Float }
deriving Generic
instance VarLength Vehicle
instance CustomValue Vehicle
instance Proc_Show Vehicle where
pshow (Vehicle loc vel acc rad maxf maxs ) =
"Vehicle: loc= " +.+ ppshow loc +.+ ", vel= " +.+ ppshow vel
+.+ ", acc= " +.+ ppshow acc
ppshow :: Proc_Point -> Proc_Text
ppshow (x,y) = "(" +.+ pshow (pround x) +.+ "," +.+ pshow (pround y) +.+ ")"
-- constructor for a new vehicle with default values
newVehicle :: Proc_Point -> Vehicle
newVehicle loc = Vehicle loc (0,-2) (0,0) 6 0.1 4
----------------------------------------------------------------}}}
--{{{ seek
seek :: ProcScript
seek = execScriptM $ do
v <- newVarC $ newVehicle (intToFloat screenWidth / 2, intToFloat screenHeight / 2)
on Setup $ do
size screenWidth screenHeight
on Draw $ do
background $ Color 255 255 255 255
mouse <- getMousePoint
-- draw an ellipse at the mouse location
fill $ Color 200 200 0 255
stroke $ Color 0 0 0 255
strokeWeight 2
circle mouse 48
-- Call the appropriate steering behaviors for our agents
vehicle <- readVarC v
let vehicle' = update (seeker vehicle mouse)
display vehicle'
writeVarC v vehicle'
----------------------------------------------------------------}}}
--{{{ seeker, applyForce, update, display
-- calculate for a vehicle and a seeking point the force to seek the point
-- and apply the force to the vehicle.
-- according the formula: STEER = DESIRED - VELOCITY
seeker :: Vehicle -> Proc_Point -> Vehicle
seeker vehicle target =
let desired = setMag (maxspeed vehicle) $ subtractP target (location vehicle)
steer = limit (maxforce vehicle) $ subtractP desired (velocity vehicle)
in applyForce vehicle steer
applyForce :: Vehicle -> Proc_Point -> Vehicle
applyForce vehicle force = vehicle { acceleration = addP (acceleration vehicle) force }
-- calculate velocity, location and reset acceleration
update :: Vehicle -> Vehicle
update vehicle =
let newVelocity = limit (maxspeed vehicle) $ addP (acceleration vehicle) (velocity vehicle)
-- Update velocity and limit speed
in vehicle { velocity = newVelocity
, location = addP newVelocity (location vehicle)
, acceleration = (0,0)
}
-- display a vehicle
display :: (ProcMonad m, Drawing c, Monad (m c)) => Vehicle -> m c ()
display vehicle = do
fill $ Color 127 10 10 255
stroke $ Color 0 0 0 255
strokeWeight 1
circle (location vehicle) 48
----------------------------------------------------------------}}}