Animated Vector Graphics Scene Graph

Share your advanced PureBasic knowledge/code with the community.
User avatar
idle
Always Here
Always Here
Posts: 6031
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

This almost works, maybe Fred should add

Code: Select all

GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count)

so we can use an array of points

Code: Select all

Structure avgpoint
  x.f
  y.f
EndStructure  

Procedure _AVGRefit_Bezier(*p0.avgpoint,*p1.avgpoint,*p2.avgpoint,*p3.avgpoint,*t0.avgpoint,*t1.avgpoint)
  
  Protected d1.f, d2.f, d3.f
  Protected a.f, b.f, c.f, d.f
  Protected tx1.f,ty1.f,tx2.f,ty2.f
  
  d1 = Sqr((*p1\x-*p0\x)*(*p1\x-*p0\x) + (*p1\y-*p0\y)*(*p1\y-*p0\y))*0.5
  d2 = Sqr((*p2\x-*p1\x)*(*p2\x-*p1\x) + (*p2\y-*p1\y)*(*p2\y-*p1\y))*0.5 
  d3 = Sqr((*p3\x-*p2\x)*(*p3\x-*p2\x) + (*p3\y-*p2\y)*(*p3\y-*p2\y))*0.5 
  
  a = d1 * d1
  b = d2 * d2
  c = (2 * d1 * d1) + (3 * d1 * d2) + (d2 * d2)
  d = 1.0 / (3 * d1 * (d1 + d2))
  
  *t0\x = (a * *p2\x - b * *p0\x + c * *p1\x) * d
  *t0\y = (a * *p2\y - b * *p0\y + c * *p1\y) * d
  
  a = d3 * d3
  b = d2 * d2
  c = (2 * d3 * d3) + (3 * d3 * d2) + (d2 * d2)
  d = 1.0 / (3 * d3 * (d3 + d2))
  
  *t1\x = (a * *p1\x - b * *p3\x + c * *p2\x) * d
  *t1\y = (a * *p1\y - b * *p3\y + c * *p2\y) * d
  
EndProcedure

Procedure AVGAddPathPolygonBezier(x,y,sides.i,majoraxis.i,minoraxis.i=0,orient.i=0,Stars=1,bPathCurve=0)
    
  Protected xx, yy, px, py, inc.f, ang.f, fin.f
  Protected ndx.f,ndy.f,dy.f,dx.f,dx1,dy1,cosOrient.f,SinOrient.f
  Protected start.i,finish.i,dz.f,i.i
  Protected t0.avgpoint,t1.avgpoint  
  
  start = 0 
  If stars 
    sides*2 
  EndIf   
  
  Dim pt.avgpoint(sides) 
  
  dz=1.0
  finish = sides 
  If finish < 3 : finish = 3 : EndIf
  If finish > 64 : finish = 64 : EndIf
  inc = Radian(360 / finish)
  finish = start + 360
  
  ang = Radian(start)
  fin = Radian(finish)
  cosOrient = Sin(Radian(orient-180)) 
  sinOrient = Cos(Radian(orient-180))  
  dx = x + (Cos(ang) * majoraxis * dz) 
  dy = y + (Sin(ang) * minoraxis * dz) 
  dx1 = dx - x 
  dy1 = dy - y
  px = x + (dx1 * sinOrient - dy1 * cosOrient) ;rotate coordinates
  py = y + (dx1 * cosOrient + dy1 * sinOrient) 
  If stars 
    dz = 0.5 
  EndIf   
  
  Protected first=0  
  i=0
  Repeat 
    
    ang + inc  
    If ang > fin : ang = fin : EndIf
    dx = x + (Cos(ang) * majoraxis * dz) 
    dy = y + (Sin(ang) * minoraxis * dz) 
    dx1 = dx - x 
    dy1 = dy - y
    ndx = x + (dx1 * sinOrient - dy1 * cosorient) 
    ndy = y + (dx1 * cosOrient + dy1 * sinorient)
    
    pt(i)\x = ndx 
    pt(i)\y = ndy 
    i+1
    
    px = ndx
    py = ndy
    
    If stars 
      If dz = 0.5 
        dz = 1.0 
      Else 
        dz = 0.5 
      EndIf   
    EndIf 
  Until ang = fin
  
  Protected segments.s 
  
  sides = ArraySize(pt())
  For i = 0 To sides
    
    _AVGRefit_Bezier(pt(i%sides),pt((i+1)%sides),pt((i+2)%sides),pt((i+3)%sides),t0,t1) 
    MovePathCursor(pt((i+1)%sides)\x,pt((i+1)%sides)\y)
    
    If bPathCurve=0 
      AddPathCurve(t0\x,t0\y,t1\x,t1\y,pt((i+2)%sides)\x,pt((i+2)%sides)\y)
    Else   
      segments + " C " + StrF(t0\x, 2) + "," + StrF(t0\y, 2) + " " + StrF(t1\x, 2) + "," + StrF(t1\y, 2) + " " + StrF(pt((i+2)%sides)\x, 2) + "," + StrF(pt((i+2)%sides)\y, 2)
    EndIf 
  
    Next
   
    segments + " Z"
    
  If bPathCurve = 1   
   AddPathSegments(segments)
  EndIf 
  
EndProcedure

OpenWindow(0, 0, 0, 500, 500, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 500, 500)

StartVectorDrawing(CanvasVectorOutput(0))

TranslateCoordinates(250,250)
MovePathCursor(0,0)

AVGAddPathPolygonBezier(0,0,5,50,50,17,1,1) ;0 uses AddPathCurve 1 uses AddPathSegments 

ClosePath()
VectorSourceColor($ff0000ff)
FillPath(#PB_Path_Preserve)
VectorSourceColor($ffff0000)
StrokePath(2)

StopVectorDrawing()

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

Post Reply