POV-Ray : Newsgroups : povray.advanced-users : Flying and bouncing debris Server Time
29 Jul 2024 12:27:29 EDT (-0400)
  Flying and bouncing debris (Message 11 to 12 of 12)  
<<< Previous 10 Messages Goto Initial 10 Messages
From: Rohan Bernett
Subject: Re: Flying and bouncing debris
Date: 29 Sep 2002 03:40:02
Message: <web.3d96ad80d26a61b2c571aa6c0@news.povray.org>
Tim: thanks for the help, it's certainly helping, but I still can't get it
to work. *sigh* Here is my code so far:
///===================
//#declare Time = clock;
#declare Time = 3.6;
#declare groundheight = 0;
#declare Gravity = 9.8; // 1.6
#declare elastic = 0.5;
#declare Actual_Position = <0,0,0>;
#declare Start_Position = <0,20,0>;
#declare Direct_Speed = <1.5,0,0>;
#declare Hit_time = 0;
#declare Actual_Direct_Speed = 0;

#declare Hit_time= -((Direct_Speed.y/Gravity)-sqrt(
pow(Direct_Speed.y/Gravity,2)+((2*Start_Position.y)/Gravity) ));
#debug "hit time="
#debug str(Hit_time,8,0)

#declare counter = 0;
#while (counter < Time)
 #declare Hit_time= -((Direct_Speed.y/Gravity)-sqrt(
pow(Direct_Speed.y/Gravity,2)+((2*Start_Position.y)/Gravity) ));

 #declare Actual_Direct_Speed = Direct_Speed - Time*Gravity*y;
 #if (counter > Hit_time)
  #declare Direct_Speed = Actual_Direct_Speed*<1,-1,1>*elastic;
 #else
  #declare Direct_Speed = Actual_Direct_Speed;
 #end
 #declare counter = counter + 0.1;
#end

#declare
Actual_Position=Start_Position+Direct_Speed*Time-y*.5*Gravity*pow(Time,2);

object{rock  translate Actual_Position} // okay, it's actually just a
sphere, for now
///=================

The two Time lines are for running the animation generation, and testing
certain points.

This is a lot harder I thought it would be. :-(

Rohan _e_ii


Post a reply to this message

From: Tim Nikias
Subject: Re: Flying and bouncing debris
Date: 29 Sep 2002 12:39:42
Message: <3d972cce@news.povray.org>
I hope this doesn't wrap...

The usage is simple:
-Declare some variables
-Place object and call macro
-Done!

It supports different sized spheres, you can set maximum
of rebounces and the minimum speed an object needs to
have for an actual rebounce, otherwise the algorithm
simplifies itself by leaving some calculations away.

I think in some formulae I mixed some + and -, was pretty
hard tracking the mistake down...

Here's the code:

//My version:

//Environmental settings:
#declare Time=clock*5;
#declare Gravity=9.8;
#declare Ground_Height=0;
#declare Ground_Friction=.9;
#declare Rebounce_Threshold=.05;
#declare Rebounce_Amount=4;

//The macro
#macro Generate_Path()
 #local _Act_DirSpeed=Object_DirSpeed;
 #local _Act_Pos=Object_Start;
 #local _Act_Timer=Time;
 #local _Stay_On_Floor=false;
 #local _Reb_Counter=0;
 //Find a hit
 #local _Hit_Time=
((_Act_DirSpeed.y/Gravity) +
 sqrt(pow(_Act_DirSpeed.y/Gravity,2) +
((2*(_Act_Pos.y-Object_Radius-Ground_Height))/Gravity) ));
 //Compare to timer...
 #while (_Hit_Time<_Act_Timer & _Hit_Time>0 & !_Stay_On_Floor)
  //Get position and speed of impact
  #local _Act_Pos= (_Act_Pos + _Act_DirSpeed*_Hit_Time -
y*.5*Gravity*pow(_Hit_Time,2))*<1,0,1> +
y*(Ground_Height+Object_Radius+.001);
  #local _Act_DirSpeed=(_Act_DirSpeed-
(y*Gravity*_Hit_Time))*<1,-1,1>*Ground_Friction;
  //Check for speed-threshold
  #if (_Act_DirSpeed.y<Rebounce_Threshold) #local _Stay_On_Floor=true; #end
  //Get remaining time
  #local _Act_Timer=_Act_Timer-_Hit_Time;
  //Generate new hit-time
  #local _Root=
pow(_Act_DirSpeed.y/Gravity,2)+((2*(_Act_Pos.y-Object_Radius-Ground_Height))
/Gravity);
  #if (_Root>0)
   #local _Hit_Time=((_Act_DirSpeed.y/Gravity)+sqrt(_Root )); #else
   #local _Hit_Time=0; #end
  #if (_Hit_Time<0) #local _Hit_Time=0; #end
  //Counting the rebounces
  #local _Reb_Counter=_Reb_Counter+1;
  #if (_Reb_Counter=Rebounce_Amount) #local _Stay_On_Floor=true; #end
 #end
 //Place on floor if required...
 #if (!_Stay_On_Floor)
  #local
_Act_Pos=_Act_Pos+_Act_DirSpeed*_Act_Timer-y*.5*Gravity*pow(_Act_Timer,2);
#else
  #local
_Act_Pos=(_Act_Pos+_Act_DirSpeed*_Act_Timer-y*.5*Gravity*pow(_Act_Timer,2))*
<1,0,1>+y*(Ground_Height+Object_Radius); #end
 //Return
 (_Act_Pos)
#end

//Generates different sized spheres
#macro Rock_Macro()
sphere{0,Object_Radius pigment{rgb x}}
#end

#declare R=seed(1);

#declare C=0;
#while (C<20)

//POV will stop with an error-message if these aren't declared PRIOR the
macro-call
#declare Object_Radius=.2+.2*rand(R); //Will also be used for the Rock-Macro
#declare
Object_Start=vnormalize(<rand(R)*2-1,rand(R)*2-1,rand(R)*2-1>)*.2+y*2;
#declare
Object_DirSpeed=vnormalize(<rand(R)*2-1,rand(R)*2-1,rand(R)*2-1>)*rand(R)*10
;

object{Rock_Macro() translate Generate_Path()}

#declare C=C+1;
#end

Hope this helps,

Tim


--
Tim Nikias
Homepage: http://www.digitaltwilight.de/no_lights/index.html
Email: Tim### [at] gmxde


Post a reply to this message

<<< Previous 10 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.