Bézier Curve?

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
User avatar
axu
Devoted Member
Posts: 854
Joined: Tue Sep 18, 2007 6:50 pm

Bézier Curve?

Post by axu » Fri Mar 07, 2008 11:21 am

Miten lasketaan bézier curve??
En saanu oikeen wikipedian kaavoista selvää

niin. ja valmista koodia ei ole pakko lähettää, mutta jos haluaa niin tietenkin saa:D
Jos tämä viesti on kirjoitettu alle 5 min. sitten, päivitä sivu. Se on saattanut jo muuttua :roll:
Image

User avatar
otto90x
Advanced Member
Posts: 349
Joined: Mon Aug 27, 2007 9:00 pm
Location: Lapinjärvi, Finland
Contact:

Re: Bézier Curve?

Post by otto90x » Fri Mar 07, 2008 5:10 pm

Tässäpä on vanhoilta foorumeilta siitä juttua. Marcoder näköjään oli tälläisen vääntänyt:

Code: Select all

SCREEN 800, 600

Const POINTSIZE = 10 // Kontrollipisteen koko
Const LINES = 20 // viivan kaarevuuden pehmeys eli kuinka monesta viivasta pisteiden väli koostuu

// Kontrollipisteet
Type POINTS
Field x // Pisteen sijainti x
Field y // Pisteen sijainti y
Field angle // Tangentin kulma
Field dist1 // Lähtevä tangentti
Field dist2 // Saapuva tangentti
Field drag // Raahataanko jotain pistettä
End Type

AddText ""
AddText "MouseRight = Lisää uusi kontrollipiste"
AddText "MouseLeft = Raahaa kontrollipisteitä"
AddText "Space = Poista kaikki"
AddText "Shift = Piilota kontrollipisteet"

Repeat
mx = MouseX()
my = MouseY()

// Poistetaan kaikki kontrollipisteet
If KeyHit(cbKeySpace) Then
For pnt.POINTS = Each POINTS
Delete pnt
Next pnt
EndIf

// lisätään uusi kontrollipiste
If MouseHit(2) Then
pnt.POINTS = New(POINTS)
pnt\x = mx
pnt\y = my
pnt\angle = 0
pnt\dist1 = 50
pnt\dist2 = 50
pnt\drag = 0
EndIf

// Käydään kaikki läpi ja piirretään
i = 0
For pnt.POINTS = Each POINTS
Gosub CalcTanPoints
Gosub SelectPoint
Gosub DrawPoint
Gosub DrawLine
// Otetaan tiedot talteen koska niitä tarvitaan seuraavan kierroksen laskennassa
prevX = pnt\x
prevY = pnt\y
prevX1 = x1
prevY1 = y1
prevX2 = x2
prevY2 = y2
i + 1
Next pnt

DrawScreen
Text 0, 0, "FPS " + FPS()
Forever

// Lasketaan tangenttien pisteet
CalcTanPoints:
x1 = pnt\x - Sin(pnt\angle) * pnt\dist1
y1 = pnt\y - Cos(pnt\angle) * pnt\dist1
x2 = pnt\x - Sin(pnt\angle + 180) * pnt\dist2
y2 = pnt\y - Cos(pnt\angle + 180) * pnt\dist2
Return

// Piirretään kontrollipiste
DrawPoint:
// Tai ei piirretäkkään jos painetaan Shiftiä
If KeyDown(cbKeyLShift) Or KeyDown(cbKeyRShift)Then Return

Color 0, 0, 255
Circle pnt\x - POINTSIZE / 2, pnt\y - POINTSIZE / 2, POINTSIZE, OFF
Color 255, 0, 0
Circle x1 - POINTSIZE / 2, y1 - POINTSIZE / 2, POINTSIZE, OFF
Circle x2 - POINTSIZE / 2, y2 - POINTSIZE / 2, POINTSIZE, OFF
Color 128, 128, 128
Line x1, y1, x2, y2
Return

// Piirretään viivat kontrollipisteiden väliin
DrawLine:
// Jos ollaan vasta ensimmäisessä pisteessä niin ei tehdä mitään
If i = 0 Then Return
Color 255, 255, 255
px = prevX
py = prevY
// Lasketaan bezier-pisteet ja piirretään viivat
For l = 1 To LINES
bx = GetBezierPoint(prevX, prevX1, x2, pnt\x, l, LINES)
by = GetBezierPoint(prevY, prevY1, y2, pnt\y, l, LINES)
Line px, py, bx, by
px = bx
py = by
Next l
Return

// Valitaan hiirellä joku kontrollipiste tai tangentti (tai sitten ei)
SelectPoint:
// Eli siis ei valita
If Not MouseDown(1) Then
pnt\drag = 0
Return
End If

If Distance(mx, my, pnt\x, pnt\y) <= POINTSIZE / 2 Then pnt\drag = 1
If Distance(mx, my, x1, y1) <= POINTSIZE / 2 Then pnt\drag = 2
If Distance(mx, my, x2, y2) <= POINTSIZE / 2 Then pnt\drag = 3

// Raahataanko jotain pistettä
If pnt\drag = 1 Then
pnt\x = mx
pnt\y = my
EndIf
If pnt\drag = 2 Then
pnt\dist1 = Distance(pnt\x, pnt\y, mx, my)
pnt\angle = GetAngle(pnt\x, pnt\y, mx, my) - 90
EndIf
If pnt\drag = 3 Then
pnt\dist2 = Distance(pnt\x, pnt\y, mx, my)
pnt\angle = GetAngle(mx, my, pnt\x, pnt\y) - 90
EndIf
Return

// Lasketaan pisteen paikka bezier-käyrälle
Function GetBezierPoint(startP#, startTanP#, endTanP#, endP#, point#, numPoints#)
t# = point * (1.0 / numPoints)
a# = (startP + t * (-startP * 3 + t * (3 * startP - startP * t)))
b# = t * (3 * startTanP + t * (-6 * startTanP + startTanP * 3 * t))
c# = t * t * (endTanP * 3 - endTanP * 3 * t)
d# = endP * t * t * t
Return (a + b + c + d)
End Function
Otto Martikainen a.k.a. MetalRain, otto90x, kAATOSade.
Runoblogi, vuodatusta ja sekoiluja.

User avatar
axu
Devoted Member
Posts: 854
Joined: Tue Sep 18, 2007 6:50 pm

Re: Bézier Curve?

Post by axu » Sat Mar 08, 2008 2:41 pm

Jes! vihdoinkin alkaa Mario Galaxy 2D edistyä :)
Jos tämä viesti on kirjoitettu alle 5 min. sitten, päivitä sivu. Se on saattanut jo muuttua :roll:
Image

Post Reply