\ ob.force \ \ hp_force \ class of object that applies a constant force to a body or bodies. \ part of the collection of software componenets: "henri poincare." \ \ description of methods: \ \ NEW: ( n -- , allocate memory for n dimensions ) \ \ GET.TYPE: ( -- id , type of particle that force can be applied to ) \ \ PUT.ENABLE: ( flag dim# -- , enable or disable one dimension ) \ GET.ENABLE: ( dim# -- flag , get enable status of dimension ) \ \ GET.SPACE: ( -- addr | 0 , returns current space address ) \ GET.PARTICLE: ( -- addr | 0 , returns current particle address ) \ \ CALC.FORCE: ( space -- , update force of each particle in space ) \ (CALC.FORCE): ( -- , calculate and store force for current particle ) \ \ based on ideas presented by Joel Ryan. \ \ Code: Han-earl Park \ Copyright 2000 Buster & Friends C-ALTO Labs \ (Den haag, December 1997 - \ (Valencia, October 1998 - \ (Southampton, February 2002 - \ \ MOD: HEP 11/12/97 Started project. \ MOD: HeP 10/11/98 Complete redesign of object classes. \ MOD: HeP 10/15/98 Change name of the collective software components \ to "forces in motion". \ MOD: HeP 10/24/98 Yet another redesign of the components with the addition \ of the space class which does all the calculation. \ thus, the puck classes no longer hold any "intelligence." \ thanks to mark trayle for suggesting this arrangement. \ MOD: HeP 10/29/98 Redesigned so that the force class acts as a pluggin to \ the space class. Thus the scheduling intelligence is \ kept part of ob.space, but the forces are polled from \ the force objects. \ MOD: HeP 10/3098 Move all the dimension enabling from the space class. \ another redesign: ob.space can only hold one force object! \ (just create a class of ob.force that can hold more than \ one force object) \ MOD: HeP 11/17/98 The methods put.enable: and get.enable: now work like the \ old put.enable.dim and get.enable.dim: To enable or \ disable all dimensions, pass -1 as the dimension number. \ MOD: HeP 11/20/98 Got rid of the instance varaible iv-force-glob-enabled? \ MOD: HeP 11/30/98 Change the stack diagram of the (calc.force): method \ from ( -- fx fy fz... ) to ( -- ) which should make \ the method easier to code. \ MOD: HeP 12/14/98 Adding method elm.calc.force: which calulates and stores \ the force value for one particle. \ MOD: HeP 07/27/99 Change name of components to "henri poincare" \ MOD: HeP 02-23-02 Add PUT.CONSTANT: and GET.CONSTANT: methods. \ \ ToDo: Standardize DEFAULT: UPDATE: RESET: and PREFAB: \ ToDo: NO internal scaling...? \ Use double numbers....? \ Use floating point....? \ ToDo: Modify particle to have "volume" and incorporates collision. \ ToDo: get rid of the put... get.enable: stuff include? task-hp_particle myt:hp_particle anew task-hp_force \ data selectors 00 constant force_enabled? 01 constant force_max 02 constant force_min \ "type" of particle \ \ the type id is in the form of a 32 bit number. The properties of a \ particle (whether it reacts to a given force) is encoded as bits that \ are turned on or off. : PARTICLE.TYPE= ( type_a type_b -- flag , true if compatible type ) and ; method (CALC.FORCE): method CALC.FORCE: method (ELM.CALC.FORCE): method ELM.CALC.FORCE: method GET.SPACE: method GET.PARTICLE: method PUT.SCALE: method GET.SCALE: method PUT.CONSTANT: method GET.CONSTANT: :class OB.FORCE iv-force-scale ;m :m INIT: ( -- ) init: super self default: [] ;m \ memory allocation \ \ subclasses may add to the number of elements used for internal storage \ by overiding the #properties: method as follows: \ \ :m #PROPERTIES: ( -- elm# ) \ #properties: super #additional_elements + \ ;m \ \ the new: method will automatically pick these up. :m #PROPERTIES: ( -- elm# , number of elements for internal storage ) 3 ;m :m NEW: ( dim# -- , assign number of dimensions ) self #properties: [] swap new: super self reset: [] ;m :m PUT.ENABLE: ( flag dim# -- , enable or disable one dimension ) force_enabled? ;m :m GET.ENABLE: ( dim# -- flag , get enable status of dimension ) ;m \ current space and particle objects :m GET.SPACE: ( -- addr | 0 , returns current space object ) iv-force-cur-space ;m :m GET.PARTICLE: ( -- addr | 0 , returns current particle object ) iv-force-cur-puck ;m :m WHERE: ( -- space elm# , current space and particle# ) iv-force-cur-space iv-force-cur-puck# ;m \ internal scaling for calculations :m PUT.SCALE: ( n -- , set to shift by n for calculations ) abs iv=> iv-force-scale ;m :m GET.SCALE: ( -- n ) iv-force-scale ;m : FORCE.SCALE.VALUE ( n -- n' , scale value ) iv-force-scale ashift ; : FORCE.UNSCALE.VALUE ( n' -- n , convert back to original range ) iv-force-scale negate ashift ; \ force constant :m PUT.CONSTANT: ( k -- , assign force constant ) iv=> iv-force-constant ;m :m GET.CONSTANT: ( -- k , retrieve force constant ) iv-force-constant ;m \ calculate force :m (ELM.CALC.FORCE): ( -- , force for current particle ) ;m :m ELM.CALC.FORCE: ( elm# space -- , calculate force for one particle ) 2dup get: [] ( -- e# sp p ) \ dup get.type: [] self get.type: [] ( -- e# sp p t1 t2 ) particle.type= IF dimension: self #dimensions! \ iv=> iv-force-cur-puck ( -- e# sp ) dup iv=> iv-force-cur-space ( -- e# sp ) many: [] iv=> iv-force-#pucks ( -- e# ) iv=> iv-force-cur-puck# ( -- ) \ self (ELM.CALC.FORCE): [] ( -- ) \ 0 iv=> iv-force-cur-space 0 iv=> iv-force-cur-puck 0 iv=> iv-force-#pucks ELSE 3drop ( e# sp p -- ) THEN ;m :m (CALC.FORCE): ( -- , calculate forces for all particles ) iv-force-#pucks 0 DO i iv-force-cur-space get: [] ( -- p ) \ dup get.type: [] self get.type: [] ( -- p t1 t2 ) particle.type= IF iv=> iv-force-cur-puck i iv=> iv-force-cur-puck# \ self (ELM.CALC.FORCE): [] ( -- ) ELSE drop THEN LOOP ;m :m CALC.FORCE: ( space -- , calculate forces for all particles ) dup iv=> iv-force-cur-space many: [] iv=> iv-force-#pucks \ dimension: self #dimensions! \ self (CALC.FORCE): [] \ 0 iv=> iv-force-cur-space 0 iv=> iv-force-cur-puck 0 iv=> iv-force-#pucks ;m \ print data and stats :m PRINT.DATA: ( -- , print data in array ) space ." enabled? #0" force_enabled? self print.element: [] cr space ." maximum #1" force_max self print.element: [] cr space ." minimum #2" force_min self print.element: [] cr ;m :m PRINT.STATS: ( -- , print non dimension specific data ) ." abs force" cr space ." max =" iv-force-max 4 .r cr space ." min =" iv-force-min 4 .r cr ;m :m PRINT: ( -- ) cr name: self cr ." Element # \ Dim#" dimension: self dup IF 0 1 .r 1 DO i 8 .r LOOP cr ELSE drop THEN \ many: self IF self print.data: [] ?pause ELSE ." No Data!!" cr THEN self print.stats: [] ;m ;class