## [solved]Math Guru II How to make a Normal little bit random FAST?

For other topics related to the FreeBASIC project or its community.
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

There's a graphic on the first page. I found a solution .. now I just have to come up with a suitable ray tracing framework.

Or use D.J. Peters' "e3d.bi" - which is hard to find on here - but it is good. I have it on my comp but most of it is beyond me. Many cups of coffee will be required
Stonemonkey
Posts: 598
Joined: Jun 09, 2005 0:08

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

I only see the cone diagram, are the effects of the randomness cumulative or is the result for each normal only ever to be within it's own initial cone?
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

I don't know what D.J. Peters was making, but I'm planning a path tracer.

If a sampling (incoming) ray hits a diffuse surface, a new sampling ray with a random direction gets sent out, based upon the surface normal
Stonemonkey
Posts: 598
Joined: Jun 09, 2005 0:08

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

There's also sse, depending on accuracy required there's the approximate reciprocal square root, I'm getting 1,000,000 vectors normalised in around 10ms on my slow laptop.

That's just a list of vectors with 16 bit alignment and normalising 8 each time through the loop though so would depend on data structures.
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

i'll take a gander at the sqr thingy
Stonemonkey
Posts: 598
Joined: Jun 09, 2005 0:08

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

Code: Select all

`randomize timertype vec3d    as single x,y,z,wend typefunction length(byval v as vec3d ptr)as single    return sqr(v->x*v->x+v->y*v->y+v->z*v->z)end functiondim as ubyte ptr vdat=new ubyte[sizeof(vec3d)*1000000+15]dim as vec3d ptr vlist=cast(vec3d ptr,(cast(ulong,vdat)+15)and &hfffffff0)for i as integer=0 to 999999    vlist[i].x=rnd*10-5    vlist[i].y=rnd*10-5    vlist[i].z=rnd*10-5nextdim as double t=timerfor i as integer=0 to 999999    dim as vec3d ptr v=@vlist[i]    dim as single d=1.0/sqr(v->x*v->x+v->y*v->y+v->z*v->z)    v->x*=d    v->y*=d    v->z*=dnextprint "FB:  ";timer-tfor i as integer=0 to 999999    vlist[i].x=rnd*10-5    vlist[i].y=rnd*10-5    vlist[i].z=rnd*10-5nextt=timerasm    mov ecx,125000    mov ebx,[vlist]normalise_loop:        movaps xmm0,[ebx]        movaps xmm1,[ebx+16]        movaps xmm2,[ebx+32]        movaps xmm3,[ebx+48]        movaps xmm4,[ebx+64]        movaps xmm5,[ebx+80]        movaps xmm6,[ebx+96]        movaps xmm7,[ebx+112]        mulps xmm0,xmm0        mulps xmm1,xmm1        mulps xmm2,xmm2        mulps xmm3,xmm3        mulps xmm4,xmm4        mulps xmm5,xmm5        mulps xmm6,xmm6        mulps xmm7,xmm7        haddps xmm0,xmm1        haddps xmm4,xmm5        haddps xmm2,xmm3        haddps xmm6,xmm7        haddps xmm0,xmm2        haddps xmm4,xmm6        rsqrtps xmm0,xmm0        rsqrtps xmm4,xmm4        movaps xmm1,xmm0        movaps xmm2,xmm0        movaps xmm3,xmm0        movaps xmm5,xmm4        movaps xmm6,xmm4        movaps xmm7,xmm4        shufps xmm0,xmm0,&b00000000        shufps xmm1,xmm1,&b01010101        shufps xmm2,xmm2,&b10101010        shufps xmm3,xmm3,&b11111111        shufps xmm4,xmm4,&b00000000        shufps xmm5,xmm5,&b01010101        shufps xmm6,xmm6,&b10101010        shufps xmm7,xmm7,&b11111111        mulps xmm0,[ebx]        mulps xmm1,[ebx+16]        mulps xmm2,[ebx+32]        mulps xmm3,[ebx+48]        mulps xmm4,[ebx+64]        mulps xmm5,[ebx+80]        mulps xmm6,[ebx+96]        mulps xmm7,[ebx+112]        movaps [ebx],xmm0        movaps [ebx+16],xmm1        movaps [ebx+32],xmm2        movaps [ebx+48],xmm3        movaps [ebx+64],xmm4        movaps [ebx+80],xmm5        movaps [ebx+96],xmm6        movaps [ebx+112],xmm7        add ebx,128        dec ecx    jnz normalise_loopend asmprint "SSE: ";timer-tprintfor i as integer=999980 to 999999    print length(@vlist[i])nextsleep`
Last edited by Stonemonkey on Dec 02, 2016 3:44, edited 1 time in total.
Stonemonkey
Posts: 598
Joined: Jun 09, 2005 0:08

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

the list of values printed out after the times is the lengths of the 'unit' vectors to give an idea of the accuracy.
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

i normalize twice in my randomiz routine so this will be great!

Code: Select all

`function v3.perp(in as float) as v3  if y=0 then return type(0, in, 0) else var s=in/sqr(z*z+x*x): return type(-z*s, 0, x*s)End functionfunction v3.cross(r as v3, slen as float) as v3  var xx=y*r.z - z*r.y  var yy=z*r.x - x*r.z  var zz=x*r.y - y*r.x  var s = slen/sqr(xx*xx+yy*yy+zz*zz)  return type(xx*s,yy*s,zz*s)End function`
Stonemonkey
Posts: 598
Joined: Jun 09, 2005 0:08

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

the vector address has to be 16 byte aligned otherwise you have to use the MOVUPS instead of MOVAPS when loading/storing to memory which is much slower and the 3D vector has to have 4 bytes padding of 0 on the end to make it 16 bytes.

EDIT: MULPS needs data to be 16 byte aligned when multiplying from memory, the only alternative to that if data isn't aligned is to load into an SSE reg using MOVUPS first then doing the multiply.
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

actually, i might understand why you asked about the cumulative effect. i may end up creating only 1 ray per hit but it should still be pretty fast. thanks for the info!

i'll later see if i can simulate your box method (rnd-0.5) and show u how it looks
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

box vects

Code: Select all

`type imagevars '2016 Nov 23 - by dafhi  ' 1. quick reference for ScreenInfo & ImageInfo  ' 2. encapsulate standard metrics  ' 3. additional-use vars  as any ptr              im, pixels  as integer              w,h,bpp,bypp,pitch,num_pages,flags,rate  as string               driver_name  as ulong ptr            p32  declare                 constructor(w as integer=0, h as integer=0, col as ulong=&HFF000000)  Declare Sub             screen_init(wid As integer=-1, hgt As integer=-1, bpp as UInteger=32, numPages as integer=1, Flags as integer=0)  declare sub             create(w as integer=0, h as integer=0, col as ulong=&HFF000000)  declare sub             fill_info(im as any ptr=0)  declare sub             checkers(pColor As ULong=RGBA(145,145,145,255), size As UInteger = 12)  as boolean              is_screen       '  as integer              pitchBy, wm, hm '  as single               midx,midy, midxm, midym, diagonal  declare destructor private:  declare sub             destroy  declare sub             release  as any ptr              hReleaseend typeconstructor imagevars(w as integer, h as integer, col as ulong) ' 2016 Aug 30  if w<1 or h<1 then exit constructor  if screenptr = 0 then  screen_init w,h  else  create w,hEnd ConstructorDestructor.imagevars  releaseEnd DestructorSub imagevars.Destroy():  If im <> 0 Then ImageDestroy im: im = 0: endif:  End Subsub imagevars.release '2016 Aug 30  w=0: h=0: bpp=0: bypp=0: im=0: pixels=0  If ImageInfo(hRelease) = 0 Then ImageDestroy hRelease:  hRelease = 0End Subsub imagevars.fill_info(im as any ptr) '2016 Nov 23  release  if im=0 then    ScreenInfo w,h, bpp, bypp, pitch, rate, driver_name:  pixels=screenptr    is_screen = -1: im=0  elseif Imageinfo(im)=0 then    ImageInfo im, w, h, bypp, pitch, pixels:  bpp = bypp * 8    this.im = im:  is_screen = 0  endif: hRelease = im:  p32=pixels  if bypp<>0 then pitchBy=pitch\bypp  wm=w-1: midx=w/2: midxm = wm/2  hm=h-1: midy=h/2: midym = hm/2  diagonal=sqr(w*w+h*h)end subsub imagevars.create(w as integer, h as integer, col as ulong)  fill_info  if bypp = 0 then exit sub  release:  fill_info imagecreate(w,h,col)End SubSub imagevars.screen_init(w As integer, h As integer, _bpp as UInteger, _numpages as integer, _flags as integer)  var scale = 1  if w<1 or h<1 then scale=.8:  ScreenInfo w,h  Destroy  ScreenRes w*scale,h*scale,_bpp,num_pages,flags: fill_info  num_pages=_numpages: flags=_flags  if num_pages > 1 then screenset 0,1End subSub imagevars.checkers(pColor As ULong, size As UInteger)  Dim As UInteger SizeDouble=size*2,SizeM=size-1  For Y as integer = 0 To hm Step size    For X as integer = -size * ((Y/SizeDouble)=Int(Y/SizeDouble)) To wm Step SizeDouble      Line im,(X,Y)-(X+SizeM,Y+SizeM),pColor,BF    Next  NextEnd Sub#Macro Alpha256A(ret,back, fore, am, a256)    '' preserves dest alpha    ret=((_    (fore And &Hff00ff) * a256 + _    (back And &Hff00ff) * am + &H800080) And &Hff00ff00) Shr 8 Or (_    ((fore Shr 8) And &Hff00ff) * a256 + _    ((back Shr 8) And &Hff00ff) * am + &H800080) And &HFF00FF00#EndMacroType aadot_info  As single               x, y                ' pos  as single               rad  = 0.65         ' 0.65 is a nice size for plotting aa curves  as single               slope = 1           ' for sharp circle, make slope = rad (in your code)  as single               a256 = 256          ' alpha value. max: 256  as ulong                col = &HFFFFFF      ' color  as ulong                fill = 1            ' outline or filled  declare property        alpha(in as single) ' 0 to 1                                              ' container udt - add your own vars if desiredEnd Typeproperty aadot_info.alpha(in as single): a256 = 256 * inend propertytype aadot ' v. 2015 Sept 21  as aadot_info           o  as aadot_info ptr       p  as imagevars ptr        piv  as any ptr              pixels  declare sub             render_target(piv as imagevars ptr)  declare sub             draw(x as single=0, y as single=0, col as ulong=&HFFFFFFFF)  declare sub             pdraw  declare constructor private:  as single               slope, slope_X2end typeconstructor aadot:p = @o:end constructorsub aadot.render_target(_piv as imagevars ptr)  if _piv->is_screen then:pixels=ScreenPtr  else:pixels = _piv->pixels:end if:piv = _pivend sub#Macro mac_aadot_draw_common(xx,yy,col,rad,fill,alpha,slope)  dim as ulong ptr  dst = piv->pixels  dim as single     r=(rad)  dim as single     salpha=(alpha)  dim as single     astep=salpha*(slope)/r  dim as single     cone_hgt=astep*r  dim as single     si=(xx)  dim as long       i=si-r, i2=si+r:  i+=i*(i<0): dst+=i  dim as long       clippedw=i2-i+(i2-piv->wm)*(i2>piv->wm)  dim as single     dLeft=(si-i)*astep  si=(yy): i=si-r: i+=i*(i<0)  dst+=piv->pitchBy*i  dim as single     dy=(si-i)*astep: i2=si+r  if fill then    for py as ulong ptr = dst to @dst[ (i2-i+(i2-piv->hm)*(i2>piv->hm)) * piv->pitchBy ] step piv->pitchBy      dim as single ySq = dy*dy, dx = dLeft      for px as ulong ptr = py to @py[clippedw]        dim as integer  alph = cone_hgt - sqr(dx*dx + ySq)        if alph > salpha then:  alph = salpha        else:  alph += alph * (alph < 0)        end if:  dim as integer  AlphM = 256 - alph        Alpha256A( *px, *px, col, AlphM, alph )        dx-=astep      next: dy-=astep    next  else    dim as single   alphaX2 = salpha*2    for py as ulong ptr = dst to @dst[ (i2-i+(i2-piv->hm)*(i2>piv->hm)) * piv->pitchBy ] step piv->pitchBy      dim as single ySq = dy*dy, dx = dLeft      for px as ulong ptr = py to @py[clippedw]        dim as long  alph = cone_hgt - sqr(dx*dx + ySq)        if alph > salpha then alph = alphaX2 - alph        if alph > 0 then          dim as integer  AlphM = 256 - alph          Alpha256A( *px, *px, col, AlphM, alph )        end if: dx-=astep      next: dy-=astep    next  end if#endmacrosub aadot.draw(xx as single=0, yy as single=0, col as ulong=&HFFFFFFFF)  mac_aadot_draw_common(xx,yy,col,o.rad,o.fill,o.a256,o.slope)end subsub aadot.pdraw()  mac_aadot_draw_common(p->x, p->y, p->col, p->rad, p->fill, p->a256, p->slope)end sub' --- UDT for independent anim / physics fps -  2016 Nov 13 - by dafhi' dim as gtPhysAni  anim            '' do                                ''   gt = Timer  'global time        ''   if anim.rdy2draw then           ''     cls                           '  --- code sample ---'     ? "fps "; anim.fps_report     ''   EndIf                           ''   x += dx * anim.phys_frames      ''   angle += anim.phys(3.14159)     'dim shared as double      gt  'global timetype gtPhysAni  as single               anim_fps = 60   'set these to whatever you want  as single               phys_fps = 243  '  declare property        fps_report as string  declare function        rdy2draw as boolean  declare function        phys_frames as integer  declare function        phys(unit_per_sec as double = 1) as double  as double               tp, td, iphys  private:  as double               phys_tp, anim_td, report_tp, report_tn  declare sub             compute_dt  as integer              fps_report_framesEnd Typefunction gtPhysAni.phys(unit_per_sec as double) as double  return phys_frames * unit_per_sec * iphysEnd Functionfunction gtPhysAni.phys_frames as integer  if phys_tp = 0 then phys_tp = timer  var frames = int(phys_fps * (gt - phys_tp) + 0.5)  iphys = 1 / phys_fps:  phys_tp += frames * iphys:  return framesEnd Functionproperty gtPhysAni.fps_report as string  static as string fps_rep  if gt >= report_tn then    var td=gt-report_tp:  fps_rep = str( int(10*fps_report_frames/td+0.5)/10 )    report_tp=report_tn: report_tn = gt+1: fps_report_frames = 0  EndIf: return fps_repEnd Propertysub gtPhysAni.compute_dt  if tp = 0 then tp = gt - 1.01/anim_fps: report_tp=gt: report_tn = tp+1  td = gt - tp:  anim_td += td  tp = gtEnd Subfunction gtPhysAni.rdy2draw as boolean  compute_dt  if anim_td >= 1 / anim_fps then fps_report_frames+=1:  anim_td- =(1/anim_fps)*int(anim_td/(1/anim_fps)):  return true  return falseEnd function' ---------------------------------------'#include "inc/vecmath.bas"#ifndef PiConst                   TwoPi = 8 * atn(1)Const                   pi    = 4 * Atn(1)Const                   piBy2 = 2 * Atn(1)const                   iPi = 1/Pi#EndIftype float as singleType v3  As double             x,y,z  declare property      len(in as float)  declare property      len as float  declare function      perp(in as float=1) as v3  declare function      cross(in as v3, slen as float=1) as v3End Typeproperty v3.len as float  return sqr(x*x+y*y+z*z)End propertyproperty v3.len(in as float)  var s = in/sqr(x*x+y*y+z*z): x*=s: y*=s: z*=sEnd Propertyfunction v3.perp(in as float) as v3  if y=0 then return type(0, in, 0) else var s=in/sqr(z*z+x*x): return type(-z*s, 0, x*s)End functionfunction v3.cross(r as v3, slen as float) as v3  var xx=y*r.z - z*r.y  var yy=z*r.x - x*r.z  var zz=x*r.y - y*r.x  var s = slen/sqr(xx*xx+yy*yy+zz*zz)  return type(xx*s,yy*s,zz*s)End functionOperator + (v1 As v3,v2 As v3) As v3  Return Type(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z)End OperatorOperator -(v1 As v3,v2 As v3) As v3  Return Type(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z)End OperatorOperator * (f As float,v1 As v3) As v3  Return type(f*v1.x,f*v1.y,f*v1.z)End OperatorOperator * (v1 As v3,f As float) As v3  Return type(f*v1.x,f*v1.y,f*v1.z)End OperatorOperator * (v1 As v3,v2 As v3) As float         'dot productReturn v1.x*v2.x+v1.y*v2.y+v1.z*v2.zEnd OperatorType Axis3D  As v3                 vX=(1,0,0), vY=(0,1,0), vZ=(0,0,1)  As double             x,y,zEnd Typetype vAxis  as v3                 x=(1,0,0), y=(0,1,0), z=(0,0,1), vEnd Type#Macro uniRot(dst,src, a,b, angle_)  Scope    Dim As single angle = (angle_)    Dim As double cosa = Cos(angle), sina = Sin(angle), temp = cosa*(src)a - sina*(src)b    (dst)b = cosa*(src)b + sina*(src)a    (dst)a = temp  End Scope#EndMacro#Macro RotC(dst, src, dota,dotb, angle)  scope    dim as single a=(angle)    uniRot(dst.vx, src.vx, dota,dotb, a)    uniRot(dst.vy, src.vy, dota,dotb, a)    uniRot(dst.vz, src.vz, dota,dotb, a)  end scope#EndMacro#Macro xRot(dst,a_)  RotC(dst,dst,.z,.y, a_)#EndMacro#Macro pRotx(dst,a_)  uniRot( dst,dst,.z,.y, a_)#EndMacro#Macro yRot(dst,a_)  RotC(dst,dst,.x,.z, a_)#EndMacro#Macro pRoty(dst,a_)  uniRot( dst,dst,.x,.z, a_)#EndMacro#Macro zRot(dst,a_)  RotC(dst,dst,.x,.y, a_)#EndMacro#Macro pRotz(dst,a_)  uniRot( dst,dst,.x,.y, a_)#EndMacroconst as ulong COLOR_X = rgb(0,200,0)const as ulong COLOR_Y = rgb(0,128,255)const as ulong COLOR_Z = rgb(255,0,0)const as ulong COLOR_CONE = rgb(255,255,255)const as ulong COLOR_INCOMING = rgb(190,255,255)const EXTRA_POINTSETS = 4 ''axes visualizationtype cv3  as v3             v  as ulong          col  as single         sizeEnd Typedim shared as cv3   gcv3()type tNormLUTvars  as float          cosa, rcos, rsin  as integer        dexEnd Typetype tNormLUT  as integer        c, ub, render_demo_lb  as tNormLUTvars   lut(any)  declare sub       transform(norm as v3, cone_angle as float=pi)  declare sub       resize(num_points as integer=100000)  declare constructor(num_points as integer=100000) private:  as single         ub_iPiEnd Typeconstructor tNormLUT(num_points as integer)  resize num_pointsEnd Constructorsub tNormLUT.resize(num_points as integer)  c=num_points:  ub=c-1:  ub_iPi = ub*iPi  redim lut(ub)  for i as integer = 0 to ub    with lut(i):  .cosa=1-i/ub      var sina = sqr(1 - .cosa*.cosa), roll=rnd*twopi      .dex=int( (1-cos((1-.cosa)*piBy2))*ub+0.5)      '' spherical      .rcos = cos(roll) * sina      .rsin = sin(roll) * sina      '' box      var x=rnd-.5      var z=rnd-.5      var s=1/sqr(x*x+.cosa*.cosa+z*z)      .cosa*=s      .rcos=x*s      .rsin=z*s    end with  next    '' visual  redim gcv3(ub+100*EXTRA_POINTSETS)  var dot_scalar = 0.012  for i as integer = 0 to ub    gcv3(i).col = COLOR_CONE    gcv3(i).size = .6 * dot_scalar  Next  for i as integer = c to c+99    var size = 1.0 * dot_scalar    gcv3(i+000) = type(rnd, 0, 0, COLOR_X, size)    gcv3(i+100) = type(0, rnd, 0, COLOR_Y, size)    gcv3(i+200) = type(0, 0, rnd, COLOR_Z, size)    if EXTRA_POINTSETS>3 then gcv3(i+300) = type(0,0,0, COLOR_INCOMING, size)  next  end subsub tNormLUT.transform(norm as v3, cone_angle as float)  var cone_ub=lut( int(cone_angle*ub_iPi + 0.5) ).dex 'dex will used by 'render' (below)  render_demo_lb=ub-cone_ub 'shift calculation to upper part of array in case of small cone_angle  for j as integer = render_demo_lb to ub    var i = j-render_demo_lb    var s = i/cone_ub    dim as v3 perp0 = norm.perp(lut(i).rcos)    gcv3(j).v = norm*lut(i).cosa + perp0 + norm.cross(perp0, lut(i).rsin)  next  if EXTRA_POINTSETS > 3 then    '' " incoming "    var i = lut( int(pi*ub_iPi*0.6 + 0.5) ).dex    dim as v3 perp0 = norm.perp(lut(i).rcos)    dim as v3 result = norm*lut(i).cosa + perp0 + norm.cross(perp0, lut(i).rsin)    result *= 1.5    var lb=ub+301    for j as integer = lb to lb+99      gcv3(j).v = result * ((j-lb)/100)    Next  endifEnd Subsub render(byref buf as imagevars ptr, nlut as tNormLUT, axis as Axis3D, zoom as single)  draw string (0,20), "incoming ", COLOR_INCOMING  dim as aadot dot  dot.render_target buf  for i as integer = nlut.render_demo_lb to ubound(gcv3)    with gcv3(i)      dim as single rz_ = (axis.z + axis.vZ.z*.v.z + axis.vX.z*.v.x + axis.vY.z*.v.y)      If rz_ > 0.1 Then        Dim As Single rz = zoom/rz_        Dim as single y = buf->midy - rz*(axis.y + axis.vX.y*.v.x + axis.vY.y*.v.y + axis.vZ.y*.v.z)        dim as single x = buf->midx + rz*(axis.x + axis.vX.x*.v.x + axis.vY.x*.v.y + axis.vZ.x*.v.z)        dot.o.rad = rz * .size        dot.draw x,y, .col      end if    end with  Nextend subtype tMouse  as integer        x,y,b, xp,yp,bp  as single         scalar = 1  declare function  buttons as integer  declare property  dx as single  declare property  dy as singleend typeproperty tmouse.dx as single  return scalar * (x-xp)end propertyproperty tmouse.dy as single  return scalar * (y-yp)end propertyfunction tmouse.buttons as integer  bp = b: xp = x: yp = y  getmouse x,y,,b  return bend functionSub Main  dim as imagevars  buf  buf.screen_init 640, 480    dim as imagevars  img = type(buf.w,buf.h, rgb(48,48,48))  img.checkers rgb(92,92,92), buf.w \ 32  dim as Axis3D     Axis  Axis.z = 30.0  yRot(axis, -pi/10)  xRot(axis, pi/10)  dim as tNormLUT   vLUT=6000  dim as v3         norm = (1,0,0)  pRotz(norm, pi/4)  dim as gtPhysAni  anim   dim as string     kstr  dim as tMouse     mouse    dim as single     rot_plane_axis = pi / 9, rot_plane_axis_inc = TwoPi / (anim.phys_fps * 300)  dim as single     rspeed_axis = TwoPi / (anim.phys_fps * 1750)  dim as single     rot_plane_norm = pi/4, rot_plane_norm_inc = rot_plane_axis_inc * 5.3  dim as single     rspeed_norm = rspeed_axis * 80  dim as single     tDemoMinutes = 3   dim as double     tProgExit=Timer+tDemoMinutes*60  dim as double     tIntroMesg=Timer+1.5   do     gt=timer    if anim.rdy2draw then      var zoom = axis.z * buf.diagonal / 4      screenlock        put (0,0), img.im, pset        vLUT.transform norm, pi*1/1        render @buf, vlut, axis, zoom        if gt <= tIntroMesg then          locate 7,20:  color rgb(0,0,0),rgb(255,255,255)          '? "demo quits after"; tDemoMinutes; " minutes"        else          locate 1,1:  color rgb(255,255,255), rgb(0,0,0)          '? "fps: ";anim.fps_report        end if      screenunlock    end If    sleep 1    var phys_f_norm = anim.phys_frames          if mouse.buttons > 0 then      mouse.scalar = Pi / buf.diagonal      yrot(axis, mouse.dx)      xrot(axis, mouse.dy)    else      var phys_f = phys_f_norm      while phys_f > 0        zRot(axis, -rot_plane_axis)        yRot(axis, rspeed_axis)        zRot(axis, rot_plane_axis)        rot_plane_axis += rot_plane_axis_inc        phys_f -= 1      wend    end if       while phys_f_norm > 0      pRotx(norm, -rot_plane_norm)      pRoty(norm, rspeed_norm)      pRotx(norm, rot_plane_norm)      rot_plane_norm += rot_plane_norm_inc      phys_f_norm -= 1    Wend        kstr=left(inkey\$,1)         if gt>=tProgExit or kstr<>"" then'chr(27) then 'kstr = ESC      locate 10,1      ? "demo finished .. exiting ..": sleep 1100     exit do    end if     Loop End SubMain`
Last edited by dafhi on Dec 02, 2016 6:19, edited 2 times in total.
Stonemonkey
Posts: 598
Joined: Jun 09, 2005 0:08

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

I'd guess slightly more normals bunched towards the corners but i was just using that as an example of how you could calculate the unit dot product of 2 un-normalised vectors with only 1 reciprocal square root.
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

im new to non gimbal-lock rotation. atm using 2 perp vects and think i have to set their lengths to represent cos, sin because cross product messes that up
Stonemonkey
Posts: 598
Joined: Jun 09, 2005 0:08

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

Not sure what you mean, i use 3 unit vectors to define rotation, just start by pointing them along each axis and rotate them all together, the only time ive found them to need any adjustment has been when ive combined them with some hierarchy.
dafhi
Posts: 1305
Joined: Jun 04, 2005 9:51

### Re: [solved]Math Guru II How to make a Normal little bit random FAST?

I'll optimize once I get comfy with the new rotation method