Bezierkurven in Geraden zerlegen

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Goodjee

Betreff: Bezierkurven in Geraden zerlegen

BeitragSa, Mai 01, 2010 16:50
Antworten mit Zitat
Benutzer-Profile anzeigen
heyho, hier ein kleiner code mit dem man bezierkurven rekursiv in geraden zerlegen kann. die können schneller gemalt werden und einfacher für kollisionsüberprüfungen benutzt werden.
hierfür werden die geraden so lange weiter zerteilt, bis der größte abstand zwischen bezierkurve und gerade kleiner als ein grenzwert ist.
ändert ihr den wert "abweichung" in der klasse Bezier könnt ihr die veränderung sehn, die kurve wird immer kantiger je höher der wert gewählt wird.

im beispielprogramm platziert ihr bezierpunkte durch mausklicks, die punkte haben eine waagerechte tangente.
viel spaß damit Very Happy
BlitzMax: [AUSKLAPPEN]
SuperStrict

Type Bezier
Field points:TList=New TList
Field drawpoints:TList=New TList

Const abweichung:Float=1.0

Method updatepart(a:BezierPoint,b:BezierPoint,from:Float=0,too:Float=1,first:Int=0)
Local x1:Float=(1-from)*(1-from)*(1-from)*a.x+ 3*from*(1-from)*(1-from)*a.tan2x+ 3*from*from*(1-from)*b.tan1x+ from*from*from*b.x
Local y1:Float=(1-from)*(1-from)*(1-from)*a.y+ 3*from*(1-from)*(1-from)*a.tan2y+ 3*from*from*(1-from)*b.tan1y+ from*from*from*b.y
Local x2:Float=(1-too)*(1-too)*(1-too)*a.x+ 3*too*(1-too)*(1-too)*a.tan2x+ 3*too*too*(1-too)*b.tan1x+ too*too*too*b.x
Local y2:Float=(1-too)*(1-too)*(1-too)*a.y+ 3*too*(1-too)*(1-too)*a.tan2y+ 3*too*too*(1-too)*b.tan1y+ too*too*too*b.y

If(first) drawpoints.addLast([x1,y1])


Local nx:Float=y2-y1
Local ny:Float=-x2+x1
Local d:Float=Sqr(nx*nx+ny*ny)
nx:/d
ny:/d
Local highscore:Float=0
Local hight:Float=from

For Local t:Float=from To too Step 0.01
Local x:Float=(1-t)*(1-t)*(1-t)*a.x+ 3*t*(1-t)*(1-t)*a.tan2x+ 3*t*t*(1-t)*b.tan1x+ t*t*t*b.x
Local y:Float=(1-t)*(1-t)*(1-t)*a.y+ 3*t*(1-t)*(1-t)*a.tan2y+ 3*t*t*(1-t)*b.tan1y+ t*t*t*b.y

Local d:Float=(x-x1)*nx+(y-y1)*ny

If(Abs(d)>highscore)
hight=t
highscore=Abs(d)
EndIf

Next

If(highscore>abweichung)
updatepart(a,b,from,hight)
updatepart(a,b,hight,too)
Else
drawpoints.addLast([x2,y2])
EndIf

EndMethod

Method update()
drawpoints=New TList
Local lastpoint:BezierPoint=Null
Local first:Int=1
For Local a:BezierPoint=EachIn points
If(lastpoint<>Null)
updatepart(lastpoint,a,0,1,first)
first=0
EndIf
lastpoint=a
Next
EndMethod

Method draw()
Local lastpoint:Float[]=Null

Local lastx1:Float
Local lasty1:Float
Local lastx2:Float
Local lasty2:Float
Local color:Byte=0
For Local a:Float[]=EachIn drawpoints

If(lastpoint<>Null)
SetColor 255,0,0
If(color) SetColor 0,0,0
color=Not color

Local normalx:Float=lastpoint[1]-a[1]
Local normaly:Float=-(lastpoint[0]-a[0])
Local s:Float=Sqr(normalx*normalx+normaly*normaly)
normalx:/s
normaly:/s

Local x1:Float=a[0]+normalx*5
Local y1:Float=a[1]+normaly*5
Local x2:Float=a[0]-normalx*5
Local y2:Float=a[1]-normaly*5

glBegin(GL_QUADS)
glVertex2f(x1,y1)
glVertex2f(x2,y2)
glVertex2f(lastx2,lasty2)
glVertex2f(lastx1,lasty1)
glEnd()

lastx1:Float=lastpoint[0]+normalx*5
lasty1:Float=lastpoint[1]+normaly*5
lastx2:Float=lastpoint[0]-normalx*5
lasty2:Float=lastpoint[1]-normaly*5


glBegin(GL_QUADS)
glVertex2f(x1,y1)
glVertex2f(x2,y2)
glVertex2f(lastx2,lasty2)
glVertex2f(lastx1,lasty1)
glEnd()

lastx1=x1
lastx2=x2
lasty1=y1
lasty2=y2
Else
lastx1=a[0]
lastx2=a[0]
lasty1=a[1]
lasty2=a[1]
EndIf

lastpoint=a
Next

EndMethod
EndType

Type BezierPoint
Field x:Float,y:Float
Field tan1x:Float,tan1y:Float
Field tan2x:Float,tan2y:Float
End Type

SetGraphicsDriver GLMax2DDriver()
Graphics 800,600
SetClsColor(255,255,255)

Local b:Bezier=New Bezier


Repeat
Cls
b.draw()
If(MouseHit(1))
Local a:BezierPoint=New Bezierpoint
a.x=MouseX()
a.y=MouseY()
a.tan1x=a.x-50
a.tan1y=a.y
a.tan2x=a.x+50
a.tan2y=a.y
b.points.addLast(a)
b.update()
EndIf
Flip
Until AppTerminate()


getestet unter linux
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group