mysterious behavior of processing
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
----------------------------------------------------------------}}}