Difference between revisions of "Simulating new functions"

565 bytes removed ,  18:19, 8 May 2006
corrected my horrible math mistakes ^^
imported>JustTim
(Moved the discussion to the "Discussion" page and put the actual solution into the "article".)
imported>JustTim
(corrected my horrible math mistakes ^^)
Line 12: Line 12:
; Internals
; Internals
short doOnce
short doOnce
float fQuestDelayTime


; Constants
; Constants
float pi
float rad
float rad
float pi
 


; Function In- and Output
; Function In- and Output
Line 23: Line 25:
float fout
float fout
float fout2
float fout2
float fout3


ref rin1
ref rin2
ref rin3
ref rout
ref rout2
;S5 FUNCTION sqrt
float sqr


;S10 FUNCTION Hypotenuse
;S10 FUNCTION Arctan
;float sqr
float t3
float n
float t5
float t7


;S20 FUNCTION getAngle
;S20 FUNCTION getAngle
;float sqr
float tan
float x
float y
float sin
float cos
float ang
float ang


; Set constants first
; Set constants first
Begin Gamemode
Begin Gamemode
   if doOnce == 0
   if doOnce == 0
    set rad to 57.2957792
     set pi to 3.1415927
     set pi to 3.1415927
    set rad to 180.0/pi
    set fQuestDelayTime to 30
     set doOnce to 1
     set doOnce to 1
   endif
   endif
Line 55: Line 50:
This is a generalized function framework that can be re-used for as many functions as you like.
This is a generalized function framework that can be re-used for as many functions as you like.


And now make stage 5 for this quest with the following code:
And now make stage 10 for this quest with the following code:
<pre>;FUNCTION float sqrt(float input)
<pre>;FUNCTION float Arctan(float tan)
if (f.fin1 <= 0)
;Approximation by Taylor Series - script by DragoonWraith
  set f.fout to 0
 
else
set f.t3 to (f.fin1 * f.fin1 * f.fin1)
  set f.sqr to f.fin1/2
set f.t5 to (f.t3 * f.fin1 * f.fin1)
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
set f.t7 to (f.t5 * f.fin1 * f.fin1)
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.sqr to (f.sqr+(f.fin1/f.sqr))/2
  set f.fout to f.sqr
endif</pre>


And stage 10:
set f.fout to (f.fin1 - (f.t3/3) + (f.t5/5) - (f.t7/7))</pre>
<pre>;FUNCTION float Hypotenuse(float CathetusA, float CathetusB)
set f.n to ((f.fin1 * f.fin1) + (f.fin2 * f.fin2))
;CALL float sqrt(float input)
set f.fin1 to f.n
setStage f 5
;fout is already the result</pre>


And stage 20:
And stage 20:
<pre>;FUNCTION float getAngle(float x, float y)
<pre>;FUNCTION float getAngle(float x, float y)
set f.x to f.fin1
set f.y to f.fin2
;CALL Hypotenuse using same fin
setStage f 10
set f.sqr to f.fout


set f.sin to (f.x/f.sqr)
set f.tan to (f.fin1/f.fin2)
set f.cos to (f.y/f.sqr)


if f.cos >= 0 && f.sin < 0 ;Q4
if f.tan >1 || f.tan < -1
   set f.ang to (f.cos*f.rad)
   set f.tan to (f.fin2/ -f.fin1)
   set f.ang to f.ang + 270
   if f.fin1 >= 0
elseif f.cos < 0 && f.sin < 0; Q3
    set f.ang to 90
  set f.ang to ((0-f.sin)*f.rad)
   else
   set f.ang to f.ang + 180
    set f.ang to -90
elseif f.cos < 0 && f.sin >= 0 ;Q2
  endif
  set f.ang to ((0-f.cos)*f.rad)
else
   set f.ang to f.ang + 90
  if f.fin2 >= 0
else ;if f.cos >= 0 && f.sin >= 0 ;Q1
    set f.ang to 0
   set f.ang to (f.sin*f.rad)
   else
    set f.ang to 180
   endif
endif
endif
set f.fout to f.ang</pre>


Okay, the function setup is complete. Now you've already got 3 functions: One to calculate the squareroot, one to calculate the Hypotenuse in a triangle and one to calculate the angle of a vector. To get the angle between two objects in a script just type:
;CALL float Arctan(float tan)
set f.fin1 to f.tan
setStage f 24
 
if f.fout > (f.pi/2)
  set f.fout to (f.pi/2)
elseif f.fout < (f.pi/ -2)
  set f.fout to (f.pi/ -2)
endif
 
set f.fout to ((f.fout*f.rad) + f.ang)</pre>
 
Okay, the function setup is complete. Now you've already got 2 functions: One to calculate the arctan and another one that uses arctan to calculate the angle of a vector. To get the angle between two objects in a script just type:
<pre>;CALL float getAngle(float x, float y)
<pre>;CALL float getAngle(float x, float y)
set f.fin1 to ( Object2.getPos x - Object1.getPos x )
set f.fin1 to ( Object2.getPos x - Object1.getPos x )
Line 119: Line 104:
The only downsides are that you have to define all vars in the quest script (it compiles when you define them in the stage result script, but they'll always be 0) and the limited maximum length of each quest result script (which isn't a big problem since you are able to split a single function into multiple stages).
The only downsides are that you have to define all vars in the quest script (it compiles when you define them in the stage result script, but they'll always be 0) and the limited maximum length of each quest result script (which isn't a big problem since you are able to split a single function into multiple stages).


Many thanks go tu Kkuhlmann for his great idea and to Galerion for the Square Root function!
Many thanks go tu Kkuhlmann for his great idea, to DragoonWraith for the Arctan function and to Maian for telling me that my old functions were completely wrong. :)
The above function isn't very accurate, which may be due to my bad mathematics skills. If anyone has an idea on how to improve these scripts for accuracy and performance then please contribute!
The new version of the getAngle Function seems to be very accurate, but if anyone has an idea on how to improve these scripts for accuracy and performance then please contribute!


[[Category:Useful Code]]
[[Category:Useful Code]]
[[Category:Solutions]]
[[Category:Solutions]]
Anonymous user