April 29, 2024, 02:24:42 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


3D Bezier Curve Example by Rich

Started by pistol350, September 04, 2007, 10:51:59 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

pistol350


'3D Bezier Curve Example
'by Rich Schafermeyer
def win:window
def x0,y0,bezdotnum,bezsegnum,bxy[10]:int
def dotstate,dotnumber,rdotnumber,winT,winL,winW,winH:int

'bezier curve: bezdotnum = number of dots that make curve (2-5), bezsegnum = number of straight lines that make up curve,
'bxy: array of x-y pairs that define control dot location in order from left [0] to right [9]
declare bezier(bezdotnum:int,bezsegnum:int,bxy[10]:int,drawdots:int)

'make main window
window win,0,0,800,600,@minbox|@maxbox|@size|@noautodraw,0,"3D Bezier Curve Example - Under Construction",main
centerwindow win
'make directx screen
if createscreen (win,800,600) < 0
    messagebox win, "Could not create DirectX screen","Error"
    closewindow win
    end
endif

run = 1

'set center
x0=500:y0=350
'initialize starting variables
bxy[0]=x0-200,y0,x0-150+rnd(200),y0-200+rnd(400),x0-100+rnd(200),y0-200+rnd(400),x0+50+rnd(200),y0-200+rnd(400),x0+200,y0
bezdotnum=5:bezsegnum=16
rdotnumber=1
'create controls
control win,"S,,20,160,101,16,0x50000000,1"
control win,"E,Edit1,130,159,70,20,0x50800800,2"
control win,"R,3 Dot Bezier,20,51,120,20,0x50000009,3"
control win,"R,4 Dot Bezier,20,74,120,20,0x50000009,4"
control win,"R,5 Dot Bezier,20,97,120,20,0x50000009,5"
setcontrolcolor win,3,0,rgb(255,255,255)
setcontrolcolor win,4,0,rgb(255,255,255)
setcontrolcolor win,5,0,rgb(255,255,255)
setcontroltext win,2,str$(bezsegnum)
setscrollrange win,1,1,32
setscrollpos win,1,bezsegnum
setstate win,5,1

gosub makerandomline

waituntil run =0
closewindow win
end

sub main
select @class
   case @idclosewindow
      run = 0
   'change number of bezier dots used
   case @IDCONTROL
      if @CONTROLID > 2
          bezdotnum=@controlid
         setfocus win
         gosub makeline
      endif
   'change number of line segments used
   case @IDHSCROLL
      select @CODE
         case @SBTHUMBPOS:case @SBTHUMBTRACK
            setscrollpos win,1,@QUAL
         case @SBLINELEFT
            setscrollpos win,1,(getscrollpos(win,1)-1)
         case @SBLINERIGHT
            setscrollpos win,1,(getscrollpos(win,1)+1)
         case @SBPAGELEFT
            setscrollpos win,1,(getscrollpos(win,1)-5)
         case @SBPAGERIGHT
            setscrollpos win,1,(getscrollpos(win,1)+5)
      endselect
      bezsegnum = getscrollpos(win,1)
      setcontroltext win,2,str$(bezsegnum)
      gosub makeline
   case @idchar
      gosub makerandomline
   case @idlbuttondn
      gosub checkfordot
   case @idrbuttondn
      bxy[rdotnumber - 1]=@mousex:bxy[rdotnumber]=@mousey
      gosub makeline
   case @idlbuttonup
      dotnumber = 0
   case @idmousemove
      if dotnumber > 0
         bxy[dotnumber - 1]=@mousex:bxy[dotnumber]=@mousey
         gosub makeline
      endif
   'reposition line when window size is changed
   case @idsize
      getclientsize win,winL,winT,winW,winH
      x0=50+winW/2:y0=50+winH/2
      if bezdotnum > 0 then gosub makerandomline
   case @iddxupdate
      dxflip win,0,0
endselect
return

sub makeline
dxfill win, rgb(255,255,255)
frontpen win,rgb(0,0,0)
move win,20,5
print win,"Hit any key to randomize control dots. Or left-click on a dot and drag."
move win,20,25
print win,"Or left-click on a dot, then right-click to move that dot to a new position."
move win,20,135
print win,"Set Number of Line Segments in Bezier Curve:"
frontpen win,rgb(200,200,200)
'draw grey guide lines
move win,x0,bxy[9]
line win,x0,bxy[1]
frontpen win,rgb(0,0,0)
line win,bxy[0],bxy[1]
line win,2*x0-bxy[0],bxy[1]
'draw right side
bezier(bezdotnum,bezsegnum,bxy,1)
'invert array to draw left side
bxy[0]=(2*x0-bxy[0])
bxy[2]=(2*x0-bxy[2])
bxy[4]=(2*x0-bxy[4])
bxy[6]=(2*x0-bxy[6])
bxy[8]=(2*x0-bxy[8])
bezier(bezdotnum,bezsegnum,bxy,0)
'restore array
bxy[0]=(2*x0-bxy[0])
bxy[2]=(2*x0-bxy[2])
bxy[4]=(2*x0-bxy[4])
bxy[6]=(2*x0-bxy[6])
bxy[8]=(2*x0-bxy[8])
return

sub makerandomline
bxy[0]=x0+rnd(200),y0+150,x0+rnd(200),y0+50+rnd(100),x0+rnd(200),y0-50+rnd(100),x0+rnd(200),y0-150+rnd(100),x0+rnd(200),y0-150
gosub makeline
return

sub bezier(bezdotnum,bezsegnum,bxy,drawdots)
def incr,i,i1,i2,i3,i4,x,y:float
def j,k:int
incr = 1/bezsegnum : i = 0: k=0
move win,bxy[0],bxy[1]
setlinestyle win,@lssolid,3
for j = 0 to bezsegnum
i1 = 1 - i : i2 = (1 - i) * i1 : i3 = (1 - i) * i2 : i4 = (1 - i) * i3
select bezdotnum
   case 2
      x=bxy[0]*i1+bxy[8]*i
      y=bxy[1]*i1+bxy[9]*i
   case 3
      x=bxy[0]*i2+bxy[4]*2*i*i1+bxy[8]*i*i
      y=bxy[1]*i2+bxy[5]*2*i*i1+bxy[9]*i*i
   case 4   
      x=bxy[0]*i3+bxy[2]*3*i*i2+bxy[6]*3*i*i*i1+bxy[8]*i^3
      y=bxy[1]*i3+bxy[3]*3*i*i2+bxy[7]*3*i*i*i1+bxy[9]*i^3
   case 5
      x=bxy[0]*i4+bxy[2]*4*i*i3+bxy[4]*6*i*i*i2
      x=x+bxy[6]*4*i^3*i1+bxy[8]*i^4
      y=bxy[1]*i4+bxy[3]*4*i*i3+bxy[5]*6*i*i*i2
      y=y+bxy[7]*4*i^3*i1+bxy[9]*i^4
endselect
if k=0
   frontpen win,rgb(0,0,0)
   k=1
else
   frontpen win,rgb(0,200,200)
   k=0
endif
   'draw line segment
   line win,x,y
i = i + incr
next j
'draw squares at start and end, open circles at control points
if drawdots = 1
   rect win,bxy[0]-3,bxy[1]-3,6,6,rgb(255,0,0),rgb(255,0,0)
   rect win,bxy[8]-3,bxy[9]-3,6,6,rgb(255,0,0),rgb(255,0,0)
   select bezdotnum
      case 3
         circle win,bxy[4],bxy[5],3,rgb(255,0,0)
      case 4
         circle win,bxy[2],bxy[3],3,rgb(0,255,0)
         circle win,bxy[6],bxy[7],3,rgb(0,0,255)
      case 5
         circle win,bxy[2],bxy[3],3,rgb(0,255,0)
         circle win,bxy[4],bxy[5],3,rgb(255,0,0)
         circle win,bxy[6],bxy[7],3,rgb(0,0,255)
   endselect
endif
return

sub checkfordot
def i:int
dotnumber = 0
for i=0 to 8 # 2
if (@mousex > (bxy[i]-4)) & (@mousex < (bxy[i]+4)) & (@mousey > (bxy[i+1]-4)) & (@mousey < (bxy[i+1]+4))
   dotnumber = i + 1
   rdotnumber = i + 1
endif
next i
return
Regards,

Peter B.