POV-Ray : Newsgroups : povray.general : Q: Sine Wave : Re: Q: Sine Wave Server Time
12 Aug 2024 13:19:52 EDT (-0400)
  Re: Q: Sine Wave  
From: Nieminen Mika
Date: 2 Feb 1999 07:11:30
Message: <36b6eb72.0@news.povray.org>
Ken <tyl### [at] pacbellnet> wrote:
: Now that I have the shape established I would like to
: rotate the face of the defining object to follow the
: curve of the wave.

:  Say I had a box(-1,1 scale<1,0.1,10>}

  The answer to this question is not as simple as Marc stated (at least
in the general case). Since I _am_ a perfectionist, I will give you the
complete mathematical answer:

  We calculate the x coordinate of the object with the formula:

PosX = WaveWidth*Index/ItemAmnt

  Now the y coordinate which we want is calculated this way:

Angle = StartAngle+2*pi*Cycles*PosX/WaveWidth
PosY = Amplitude*sin(Angle)

  What we now need to achieve what you want is the arcus tangent of the
slope at the current position in the sine function. For this we need to
calculate the derived function of the above. Above we have acutally this:

Amplitude*sin(StartAngle+2*pi*Cycles*PosX/WaveWidth)

  The derived function of this function is:

Amplitude*cos(StartAngle+2*pi*Cycles*PosX/WaveWidth)*2*pi*Cycles/WaveWidth

ie:

Amplitude*cos(Angle)*2*pi*Cycles/WaveWidth

  Now this is the slope (ie. the tangent) of the function at the current
point. To get the angle we need to calculate the arcus tangent of this. Ie:

RotAngle = atan(Amplitude*cos(Angle)*2*pi*Cycles/WaveWidth)

  So we can now rewrite the code to achieve what you want:

//-------------------------------------------------------------------------

// I'm not completely sure about the terms used here; correct as needed
#declare Amplitude=1;
#declare Cycles=3;
#declare StartAngle=pi*3/2;

#declare WaveStartX=-5;
#declare WaveWidth=10;

#declare ItemAmnt=50;
#declare Item=
box { -1,1 scale <1,.1,5>*.2 pigment { rgb <1,0,0> } finish { specular .5 } }

//---

#declare Index=0;
#while(Index<ItemAmnt)
  #declare PosX=WaveWidth*Index/ItemAmnt;
  #declare Angle=StartAngle+2*pi*Cycles*PosX/WaveWidth;
  #declare PosY=Amplitude*sin(Angle);
  #declare RotAngle=atan2(Amplitude*cos(Angle)*2*pi*Cycles/WaveWidth,1);
  #declare PosX=PosX+WaveStartX;
  object
  { Item
    rotate z*degrees(RotAngle)
    translate <PosX,PosY,0>
  }
  #declare Index=Index+1;
#end

//---

camera { location -z*20 look_at 0 angle 35 }
light_source { <100,150,-100> 1 }

//-------------------------------------------------------------------------


  Real coders are not afraid of mathematics!

-- 
main(i){char*_="BdsyFBThhHFBThhHFRz]NFTITQF|DJIFHQhhF";while(i=
*_++)for(;i>1;printf("%s",i-70?i&1?"[]":" ":(i=0,"\n")),i/=2);} /*- Warp. -*/


Post a reply to this message

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