Ooops
March 01, 2021, 11:06:10 PM

Author Topic: [bmx] Catmull perimeter by TAS [ 1+ years ago ]  (Read 412 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Catmull perimeter by TAS [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : Catmull perimeter
Author : TAS
Posted : 1+ years ago

Description : Use the space bar to generate a new random perimeter and then drag any control point with the left mouse button.

Code :
Code: BlitzMax
  1. 'Catmull perimeter
  2. 'By Thomas Stevenson
  3. 'war-game-programming.com
  4. 'Adapted from code by ImaginaryHuman which was
  5. 'Adapted from code by Warpy and Matt McFarland
  6.  
  7. Type Point
  8.         Field x:Int
  9.         Field y:Int
  10. End Type
  11.  
  12. Const Accuracy:Double=0.05              'Lower has more line segments
  13.        
  14. SeedRnd(MilliSecs())    'Different each time
  15. SetGraphicsDriver GLMax2DDriver()
  16. Graphics 800,600,0
  17. SetBlend LIGHTBLEND
  18. Local ControlPoint:Int
  19. Local Counter:Int      
  20. glEnable(GL_LINE_SMOOTH)        'Quick antaliasing hack
  21. glHint(GL_LINE_SMOOTH_HINT,GL_NICEST)
  22. glLineWidth(3.0)
  23.  
  24. Local NumPoints=Rand(4,30)     
  25. Local Points:Point[]=Catmull_Create(NumPoints)
  26.  
  27. Repeat
  28.         Cls
  29.         If MouseDown(1)
  30.                 'check for point drag
  31.                 ControlPoint=Catmull_Find(Points)
  32.                 If ControlPoint
  33.                         'Catmull_Find() returns NumPoints for point 0
  34.                         ControlPoint=ControlPoint Mod NumPoints
  35.                         'if non 0 then mouse is near (+/-7) of a control point
  36.                         Points[ControlPoint].x=MouseX()
  37.                         Points[ControlPoint].y=MouseY()
  38.                 EndIf
  39.         EndIf
  40.  
  41.         'Draw segments
  42.         Counter=Catmull_Draw(Points,$00FFFFFF)
  43.         'Info text
  44.         DrawText "Control Points: "+String(NumPoints),10,5
  45.         DrawText "Segiments (cps/0.05): "+String(Counter),10,20
  46.         DrawText "Curves (=cps): "+String(NumPoints),10,35
  47.        
  48.         DrawText "Spacebar: New random shape",550,10
  49.         DrawText "Escape:  Exit",550,30
  50.         DrawText "Left Mouse: Drag points",550,50
  51.         Catmull_Info(Points,60)
  52.         Flip
  53.        
  54.         If KeyHit(KEY_SPACE)
  55.                 NumPoints=Rand(7,30)
  56.                 Points=Catmull_Create(NumPoints)        'returns array of point types
  57.         EndIf  
  58.         If KeyHit(KEY_ESCAPE) Then Exit
  59.         If AppTerminate() Then Exit
  60. Forever
  61. End
  62.  
  63. Function Catmull_Draw(p:Point[],clr)
  64.                 Local PrevX:Double,PrevY:Double
  65.                 Local bytes:Byte Ptr = Varptr clr
  66.                 SetColor bytes[2],bytes[1],bytes[0]
  67.                 Local CM_Counter=0
  68.                 'Accuracy = constant set by Main
  69.                 a:Double=0.5
  70.                 For i=1 To p.length
  71.                         'calc indexs of four control points for curve from i to i+1
  72.                         'wrap index if Sj>=p.length
  73.                         s0=(i-1); s1=(i+0) Mod p.length;        s2=(i+1) Mod p.length;  s3=(i+2) Mod p.length
  74.                         For T:Double=0 To 1 Step Accuracy
  75.                                 x:Double=a*( (2*p[S1].x)+(p[S2].x-p[S0].x)*T..
  76.                                 +(2*p[S0].x-5*p[S1].x+4*p[S2].x-p[S3].x)*T*T..
  77.                                 +(3*p[S1].x-p[S0].x-3*p[S2].x+p[S3].x) *T*T*T)
  78.                                 Y:Double=a*( (2*p[S1].y)+(p[S2].y-p[S0].y)*T +(2*p[S0].y-5*p[S1].y+4*p[S2].y-p[S3].y)*T*T +(3*p[S1].y-p[S0].y-3*p[S2].y+p[S3].y) *T*T*T)
  79.                                 If PrevX=0 And PrevY=0
  80.                                         PrevX=X; PrevY=Y
  81.                                 EndIf
  82.                                 DrawLine PrevX,PrevY,X,Y,False
  83.                                 PrevX=X; PrevY=Y
  84.                                 CM_Counter:+1
  85.                         Next
  86.                 Next
  87.                 Return CM_Counter
  88. End Function
  89.  
  90. Function Catmull_Create:Point[](np,r1=80,r2=230)
  91.         Local Pts:Point[]=New Point[np]
  92.         For p:Int=0 To np-1
  93.                 Local deg:Int=P*(360/np) Mod 360
  94.                 Pts[p]=New Point
  95.                 Local h=Rand(r1,r2)
  96.                 Pts[p].x=400+h*Cos(deg)
  97.                 Pts[p].y=300+h*Sin(deg)
  98.         Next
  99.         Return Pts
  100. End Function
  101.  
  102. Function Catmull_Info(p:Point[],y)
  103.         'Draw controls excluding duplicates
  104.         For i=0 To p.length-1
  105.                 SetColor $88,$88,$88    'mark the point
  106.                 DrawLine p[i].x-7,p[i].y-7,p[i].x+7,p[i].y+7
  107.                 DrawLine p[i].x-7,p[i].y+7,p[i].x+7,p[i].y-7
  108.                 SetColor 255,0,0        'point number
  109.                 DrawText i,p[i].x+5,p[i].y+5
  110.                 SetColor 255,255,255    'xy info
  111.                 DrawText RSet(i,3)+RSet(P[i].x,6)+RSet(P[i].y,6),10,y+i*15
  112.         Next
  113. End Function
  114.  
  115. Function Catmull_Find(p:Point[])
  116.         'Point 0= Point n
  117.         If InsideRect(MouseX(),MouseY(),p[0].x-7,p[0].y-7,14,14) Then Return p.length
  118.         For i=1 To p.length-1
  119.                 If InsideRect(MouseX(),MouseY(),p[i].x-7,p[i].y-7,14,14) Then Return i
  120.         Next
  121.         'Not found
  122.         Return 0
  123. End Function
  124.  
  125. Function InsideRect(x,y,x2,y2,w,h)
  126.         If x<x2 Then Return False      
  127.         If x>(x2+w) Then Return False  
  128.         If y<y2 Then Return False      
  129.         If y>(y2+h) Then Return False  
  130.         Return True
  131. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal