Die Tangentensteigung in Abhängigkeit von i ist nicht schwierig, dafür braucht man nur die Ableitung nach i:
Für die exakte Länge müsste man davon nun die Norm bilden (also sqr(difX^2+ difY^2) und das Ergebnis dann in t=0..1 integrieren.
Hier mal der erweiterte Original-code.
Der zeigt nun eine Tangente an, wobei deren Position und die Approximationsgüte der Kurve einstellbar ist:
Code: Alles auswählen
; Bezier-curves
; based on source by Rob, extended functionality by Froggerprogger
; 19.07.05
cw = RGB(255,255,255)
cr = RGB(255,0,0)
Procedure bezier(x1,y1,x2,y2,x3,y3,x4,y4, color, smoothness.f, tangentePos.f)
; smoothness in ]0,1] : gives the approximation, typical ~= 0.05
; tangentePos in ]0,1[ : gives the point where to draw the tangent
oldx=x1
oldy=y1
cx.f=3*(x2-x1)
bx.f=3*(x3-x2)-cx
ax.f=x4-x1-cx-bx
cy.f=3*(y2-y1)
by.f=3*(y3-y2)-cy
ay.f=y4-y1-cy-by
tangente = #False
While i.f < 1.0
i+smoothness
x=((ax*i+bx)*i+cx)*i+x1
y=((ay*i+by)*i+cy)*i+y1
If i>0
If i < 1.0 - smoothness
LineXY(oldx,oldy,x,y,color)
length = length + Sqr(Pow(x-oldx, 2) + Pow(y-oldy, 2))
Else
LineXY(oldx,oldy,x4,y4,color)
length = length + Sqr(Pow(x4-oldx, 2) + Pow(y4-oldy, 2))
i = 1.0
EndIf
EndIf
If i>=tangentePos And tangente = #False:
difX = cx + i * (bx + ax * i) + i * (bx + 2 * ax * i)
difY = cy + i * (by + ay * i) + i * (by + 2 * ay * i)
LineXY(x-difX,y-difY, x+difX, y+difY, RGB(100,100,100))
tangente = #True
EndIf
oldx=x
oldy=y
Wend
FrontColor(255,255,255)
DrawingMode(1)
Locate(10,10)
DrawText("length: " + StrF(length))
Locate(10,30)
DrawText("tangent-gradient (x/y): " + StrF(difX) +" / " + StrF(difY))
Locate(10,50)
DrawText("tangent-position (%): " + StrF(tangentePos * 100) + " <Up/Down>")
Locate(10,70)
DrawText("smoothness: " + StrF(smoothness) + " <Left/Right>" )
EndProcedure
InitSprite()
InitKeyboard()
InitMouse()
If OpenScreen(1024,768,32,"Bezier") = 0
If OpenScreen(1024,768,24,"Bezier") = 0
If OpenScreen(1024,768,32,"Bezier") = 0
End
EndIf
EndIf
EndIf
MouseLocate(100,100)
x1=100 : y1=100
x2=924 : y2=100
x3=100 : y3=668
x4=924 : y4=668
smoothness.f = 0.05
tangentePos.f = 0.5
key = 1
Repeat
ExamineKeyboard()
ExamineMouse()
; change points
If MouseButton(1) And mousepush=0 ; rotate points: 1-4
key = (key % 4) + 1
If key=1 : MouseLocate(x1,y1) : EndIf
If key=2 : MouseLocate(x2,y2) : EndIf
If key=3 : MouseLocate(x3,y3) : EndIf
If key=4 : MouseLocate(x4,y4) : EndIf
EndIf
mousepush=MouseButton(1)
StartDrawing(ScreenOutput())
DrawingMode(4)
; draw points
If key=1 : x1=MouseX() : y1=MouseY() : Circle(x1,y1,5,cr) : Else : Circle(x1,y1,5,cw) : EndIf
If key=2 : x2=MouseX() : y2=MouseY() : Circle(x2,y2,5,cr) : Else : Circle(x2,y2,5,cw) : EndIf
If key=3 : x3=MouseX() : y3=MouseY() : Circle(x3,y3,5,cr) : Else : Circle(x3,y3,5,cw) : EndIf
If key=4 : x4=MouseX() : y4=MouseY() : Circle(x4,y4,5,cr) : Else : Circle(x4,y4,5,cw) : EndIf
; draw bezier-curve
bezier(x1,y1,x2,y2,x3,y3,x4,y4,cw,smoothness,tangentePos)
StopDrawing()
; handle keyboard-events
If KeyboardReleased(#PB_Key_Up)
tangentePos + smoothness
ElseIf KeyboardReleased(#PB_Key_Down)
tangentePos - smoothness
EndIf
If tangentePos <= smoothness
tangentePos = smoothness
ElseIf tangentePos >= 1.0 - smoothness
tangentePos = 1.0 - smoothness
EndIf
If KeyboardPushed(#PB_Key_Left)
smoothness - 0.0001
ElseIf KeyboardPushed(#PB_Key_Right)
smoothness + 0.0001
EndIf
If smoothness <= 0.01
smoothness = 0.01
ElseIf smoothness >= 1
smoothness = 1.0
EndIf
FlipBuffers()
ClearScreen(0,0,0)
Until KeyboardPushed(#PB_Key_Escape)