[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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 01, 2016 23:44

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: 551
Joined: Jun 09, 2005 0:08

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

Postby Stonemonkey » Dec 02, 2016 1:58

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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 02, 2016 2:58

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: 551
Joined: Jun 09, 2005 0:08

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

Postby Stonemonkey » Dec 02, 2016 3:29

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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 02, 2016 3:35

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

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

Postby Stonemonkey » Dec 02, 2016 3:39

Code: Select all

randomize timer

type vec3d
    as single x,y,z,w
end type

function length(byval v as vec3d ptr)as single
    return sqr(v->x*v->x+v->y*v->y+v->z*v->z)
end function

dim 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-5
next

dim as double t=timer
for 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*=d
next
print "FB:  ";timer-t

for i as integer=0 to 999999
    vlist[i].x=rnd*10-5
    vlist[i].y=rnd*10-5
    vlist[i].z=rnd*10-5
next

t=timer
asm
    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_loop
end asm
print "SSE: ";timer-t
print

for i as integer=999980 to 999999
    print length(@vlist[i])
next

sleep
Last edited by Stonemonkey on Dec 02, 2016 3:44, edited 1 time in total.
Stonemonkey
Posts: 551
Joined: Jun 09, 2005 0:08

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

Postby Stonemonkey » Dec 02, 2016 3:41

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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 02, 2016 4:00

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 function

function 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: 551
Joined: Jun 09, 2005 0:08

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

Postby Stonemonkey » Dec 02, 2016 4:09

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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 02, 2016 4:28

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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 02, 2016 5:32

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              hRelease
end type
constructor 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,h
End Constructor
Destructor.imagevars
  release
End Destructor
Sub imagevars.Destroy():  If im <> 0 Then ImageDestroy im: im = 0: endif:  End Sub
sub 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 = 0
End Sub
sub 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 sub
sub 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 Sub
Sub 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,1
End sub
Sub 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
  Next
End 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
#EndMacro

Type 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 desired
End Type
property aadot_info.alpha(in as single): a256 = 256 * in
end property

type 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_X2
end type
constructor aadot:p = @o:end constructor
sub aadot.render_target(_piv as imagevars ptr)
  if _piv->is_screen then:pixels=ScreenPtr
  else:pixels = _piv->pixels:end if:piv = _piv
end 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
#endmacro
sub 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 sub
sub 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 time

type 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_frames
End Type
function gtPhysAni.phys(unit_per_sec as double) as double
  return phys_frames * unit_per_sec * iphys
End Function
function 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 frames
End Function
property 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_rep
End Property
sub 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 = gt
End Sub
function 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 false
End function

' ---------------------------------------
'#include "inc/vecmath.bas"

#ifndef Pi
Const                   TwoPi = 8 * atn(1)
Const                   pi    = 4 * Atn(1)
Const                   piBy2 = 2 * Atn(1)
const                   iPi = 1/Pi
#EndIf

type float as single

Type 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 v3
End Type
property v3.len as float
  return sqr(x*x+y*y+z*z)
End property
property v3.len(in as float)
  var s = in/sqr(x*x+y*y+z*z): x*=s: y*=s: z*=s
End Property
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 function
function 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

Operator + (v1 As v3,v2 As v3) As v3
  Return Type(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z)
End Operator
Operator -(v1 As v3,v2 As v3) As v3
  Return Type(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z)
End Operator
Operator * (f As float,v1 As v3) As v3
  Return type(f*v1.x,f*v1.y,f*v1.z)
End Operator
Operator * (v1 As v3,f As float) As v3
  Return type(f*v1.x,f*v1.y,f*v1.z)
End Operator
Operator * (v1 As v3,v2 As v3) As float         'dot product
Return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z
End Operator


Type Axis3D
  As v3                 vX=(1,0,0), vY=(0,1,0), vZ=(0,0,1)
  As double             x,y,z
End Type

type vAxis
  as v3                 x=(1,0,0), y=(0,1,0), z=(0,0,1), v
End 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_)
#EndMacro


const 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 visualization

type cv3
  as v3             v
  as ulong          col
  as single         size
End Type

dim shared as cv3   gcv3()


type tNormLUTvars
  as float          cosa, rcos, rsin
  as integer        dex
End Type

type 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_iPi
End Type
constructor tNormLUT(num_points as integer)
  resize num_points
End Constructor
sub 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 sub
sub 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
  endif
End Sub

sub 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
  Next
end sub


type 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 single
end type
property tmouse.dx as single
  return scalar * (x-xp)
end property
property tmouse.dy as single
  return scalar * (y-yp)
end property
function tmouse.buttons as integer
  bp = b: xp = x: yp = y
  getmouse x,y,,b
  return b
end function


Sub 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 Sub

Main
Last edited by dafhi on Dec 02, 2016 6:19, edited 2 times in total.
Stonemonkey
Posts: 551
Joined: Jun 09, 2005 0:08

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

Postby Stonemonkey » Dec 02, 2016 5:34

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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 02, 2016 6:10

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: 551
Joined: Jun 09, 2005 0:08

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

Postby Stonemonkey » Dec 02, 2016 17:16

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: 1258
Joined: Jun 04, 2005 9:51

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

Postby dafhi » Dec 02, 2016 21:24

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

Return to “Community Discussion”

Who is online

Users browsing this forum: No registered users and 2 guests