Click to See Complete Forum and Search --> : Anti-Aliasing Bezier Curves
cyborg
Oct 9th, 2002, 10:08 PM
Hi!
I've made a program that draws bezier curves and now i was to anti-alias them!
Does anyone know how to do this?
Zaei
Oct 9th, 2002, 10:09 PM
Find an antialiased line drawing function, and use that to draw the curve =).
Z.
cyborg
Oct 9th, 2002, 10:10 PM
were can i find that?
Zaei
Oct 9th, 2002, 10:15 PM
Google.
Z.
cyborg
Oct 9th, 2002, 11:16 PM
ok....i've found alot of things but i dont know how to use it in my app! :(
cant anyone give me a sub routine for anti-aliased lines?
falcore20
Oct 10th, 2002, 12:57 AM
if you find one please let me know. I've had no such luck anti aliasing my bresenham line. There are anti aliasing algorithms out there though. I just haven't seen many written in VB. Most are written in C or another language like that.
Zaei
Oct 10th, 2002, 10:52 AM
Private Sub AntiAliasedLine(ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single)
Dim spx As Single, epx As Single
Dim spy As Single, epy As Single
Dim ax As Double, bx As Double, cx As Double, dx As Double
Dim ay As Double, by As Double, cy As Double, dy As Double
Dim ex As Double, ey As Double
Dim mp5 As Single, pp5 As Single
Dim rex As Integer, rey As Integer
Dim trz As Double, tri As Double
Dim lwris As Double, lwrun As Double
Dim zsl As Single
Dim slope As Double, lsope As Double
Dim midx As Double, midy As Double
Dim sl2 As Single
Dim distanc1 As Double, distanc2 As Double
Dim diagonal As Boolean
Dim a As Single
Dim st As Integer
Dim one As Single
Static sr(0 To 128) As Single
Static firstrun As Boolean
Dim w As Byte
If Not firstrun Then 'Initialize some things
sr(0) = 0: sr(128) = 0.5
For w = 1 To 127
sr(w) = (w / 128) ^ 2 / 2
Next w
'Initialize an array which maps a curve of 256 Single values
pow = 1 / (1 + shape / 255)
For w = 1 To 254
gs(w) = (w / 255) ^ pow
Next w: gs(0) = 0: gs(255) = 1
firstrun = 1: End If
If x1 < x2 Then
epy = y2: epx = x2
spy = y1: spx = x1
Else
spy = y2: spx = x2
epy = y1: epx = x1: End If
If epx = spx Or epy = spy Then
diagonal = 0
If epy > spy Then
st = 1
Else: st = -1: End If
Else: slope = (epy - spy) / (epx - spx): lsope = -1 / slope
diagonal = 1: End If
midx = 0.5 * lsope: midy = 0.5 * slope
sl2 = slope * slope: one = 1 / Sqr(1 + sl2)
lwris = 1 - (one - Abs(slope) + sl2 * one)
lwrun = lwris * Abs(lsope)
distanc1 = 0.5 * one
distanc2 = slope * distanc1
ax = spx - distanc1 - distanc2
ay = spy + distanc1 - distanc2
bx = epx + distanc1 - distanc2
by = epy + distanc1 + distanc2
cx = epx + distanc1 + distanc2
cy = epy - distanc1 + distanc2
dx = spx - distanc1 + distanc2
dy = spy - distanc1 - distanc2
one = 255 * (1 - 0.5 * lwris * lwrun)
If diagonal Then
If slope > 0 Then
If slope <= 1 Then
ey# = slope# * (Round(ax#) + 1.5 - ax#) + ay#
rey% = Round(ey#): mp5! = rey% - 0.5: pp5! = mp5! + 1
tri# = pp5! - lwris#: trz = pp5! - slope#: zsl! = mp5! - midy
For ex# = Round(ax#) + 1.5 To Round(bx#) - 1.5 Step 1
If ey# > tri# Then
Call DrawPixel(Int(ex# + 1), rey%, gs(one!))
Else
If ey# > trz Then
Call DrawPixel(Int(ex# + 1), rey%, gs(255 * (1 + lsope# * sr(Int((pp5! - ey#) * 128)))))
Else: Call DrawPixel(Int(ex# + 1), rey%, gs(255 * (ey# - zsl!))): End If
End If
If ey# > trz Then
pp5! = pp5! + 1: tri# = tri# + 1: trz = trz + 1
zsl! = zsl! + 1: rey% = rey% + 1: End If
ey = ey# + slope: Next ex#
ey# = cy# - slope# * (cx# - Round(cx#) + 1.5)
rey% = Round(ey#): mp5! = rey% - 0.5: pp5! = mp5! + 1: zsl! = pp5! + midy
tri# = mp5! + lwris: trz = mp5! + slope
For ex# = Round(cx#) - 1.5 To Round(dx#) + 1.5 Step -1
If ey# > tri# Then
If ey# > trz Then
Call DrawPixel(Int(ex#), rey%, gs(255 * (zsl! - ey#)))
Else: Call DrawPixel(Int(ex#), rey%, gs(255 * (1 + lsope# * sr(Int((ey# - mp5!) * 128)))))
End If
End If
If ey# < trz Then
mp5! = mp5! - 1: tri# = tri# - 1: trz = trz - 1
zsl! = zsl! - 1: rey% = rey% - 1: End If
ey# = ey# - slope: Next ex#
ex# = cx# + lsope * (cy# - Round(cy#) + 0.5)
For ey# = Round(cy#) - 0.5 To Round(dy#) + 1.5 Step -1
rex% = Round(ex#)
Call DrawPixel(rex%, Int(ey#), gs(255 * (slope# * sr(Int((ex# - rex% + 0.5) * 128)))))
ex# = ex# + lsope#: Next ey#
ex# = ax# - lsope# * (Round(ay#) + 0.5 - ay#)
For ey# = Round(ay) + 0.5 To Round(by) - 0.5 Step 1
rex% = Round(ex#)
Call DrawPixel(rex%, Int(ey# + 1), gs(255 * (slope# * sr(Int((rex% + 0.5 - ex#) * 128)))))
ex# = ex# - lsope#: Next ey#
Else
ex# = dx# - lsope# * (Round(dy#) + 1.5 - dy#): rex% = Round(ex#): mp5! = rex% - 0.5
pp5! = mp5! + 1: tri# = pp5! - lwrun: trz = pp5! + lsope: zsl! = mp5! + midx
For ey# = Round(dy#) + 1.5 To Round(cy#) - 0.5 Step 1
If ex# > tri# Then
Call DrawPixel(rex%, Int(ey# + 1), gs(one!))
Else
If ex# > trz Then
Call DrawPixel(rex%, Int(ey# + 1), gs(255 * (1 - slope * sr(Int((pp5! - ex#) * 128)))))
Else: Call DrawPixel(rex%, Int(ey# + 1), gs(255 * (ex# - zsl!))): End If
End If
If ex# > trz Then
tri# = tri# + 1: trz = trz + 1: pp5! = pp5! + 1
zsl! = zsl! + 1: rex% = rex% + 1: End If
ex# = ex# - lsope#: Next ey#
ex# = bx# + lsope# * (by# - Round(by#) + 0.5): rex% = Round(ex#): mp5! = rex% - 0.5
pp5! = mp5! + 1: tri# = mp5! + lwrun: trz = mp5! - lsope: zsl! = pp5! - midx#
For ey# = Round(by#) - 0.5 To Round(ay#) + 1.5 Step -1
If ex# > tri# Then
If ex# < trz Then
Call DrawPixel(rex%, Int(ey#), gs(255 * (1 - slope# * sr(Int((ex# - mp5!) * 128)))))
Else: Call DrawPixel(rex%, Int(ey#), gs(255 * (zsl! - ex#))): End If
End If
If ex# < trz Then
tri# = tri# - 1: trz = trz - 1: mp5! = mp5! - 1
rex% = rex% - 1: zsl! = zsl! - 1: End If
ex# = ex# + lsope#: Next ey#
ey# = dy# + slope# * (Round(dx#) + 0.5 - dx#)
For ex# = Round(dx#) + 0.5 To Round(cx#) - 1.5 Step 1
rey% = Round(ey#)
Call DrawPixel(Int(ex# + 1), rey%, gs(255 * (-lsope# * sr(Int((rey% + 0.5 - ey#) * 128)))))
ey# = ey# + slope#: Next ex#
ey# = ay# + slope# * (Round(ax#) + 1.5 - ax#)
For ex# = Round(ax#) + 1.5 To Round(bx#) - 0.5 Step 1
rey% = Round(ey#)
Call DrawPixel(Int(ex#), rey%, gs(255 * (-lsope# * sr(Int((ey# - rey% + 0.5) * 128)))))
ey# = ey# + slope: Next ex#
End If
Else
If slope > -1 Then
ey# = dy# + slope# * (Round(dx#) + 1.5 - dx#)
rey% = Round(ey#): mp5! = rey% - 0.5: pp5! = mp5! + 1: zsl! = pp5! - midy#
tri# = mp5! + lwris: trz = mp5! - slope#
For ex# = Round(dx#) + 1.5 To Round(cx#) - 1.5 Step 1
If ey# < tri# Then
Call DrawPixel(Int(ex# + 1), rey%, gs(one!))
Else
If ey# < trz Then
Call DrawPixel(Int(ex# + 1), rey%, gs(255 * (1 - lsope# * sr(Int((ey# - mp5!) * 128)))))
Else: Call DrawPixel(Int(ex# + 1), rey%, gs(255 * (zsl! - ey#))): End If
End If
If ey# < trz Then
mp5! = mp5! - 1: zsl! = zsl! - 1: tri# = tri# - 1
rey% = rey% - 1: trz = trz - 1: End If
ey# = ey# + slope#: Next ex#
ey# = by# - slope# * (bx# - Round(bx#) + 1.5)
rey% = Round(ey#): mp5! = rey% - 0.5: pp5! = mp5! + 1: zsl! = mp5! + midy#
tri# = pp5! - lwris: trz = pp5! + slope#
For ex# = Round(bx#) - 1.5 To Round(ax#) + 1.5 Step -1
If ey# < tri# Then
If ey# < trz Then
Call DrawPixel(Int(ex#), rey%, gs(255 * (ey# - zsl!)))
Else
Call DrawPixel(Int(ex#), rey%, gs(255 * (1 - lsope# * sr(Int((pp5! - ey#) * 128)))))
End If
End If
If ey# > trz Then
rey% = rey% + 1: pp5! = pp5! + 1: zsl! = zsl! + 1
tri# = tri# + 1: trz = trz + 1: End If
ey# = ey# - slope#: Next ex#
ex# = ax# + lsope# * (ay# - Round(ay#) + 1.5)
For ey# = Round(ay#) - 1.5 To Round(by#) + 0.5 Step -1
rex% = Round(ex#)
Call DrawPixel(rex%, Int(ey# + 1), gs(255 * (-slope * sr(Int((ex# - rex% + 0.5) * 128)))))
ex# = ex# + 2 * midx#: Next ey#
ex# = cx# - lsope# * (Round(cy#) + 1.5 - cy#)
For ey# = Round(cy#) + 1.5 To Round(dy#) - 0.5
rex% = Round(ex#)
Call DrawPixel(rex%, Int(ey#), gs(255 * (-slope# * sr(Int((rex% + 0.5 - ex#) * 128)))))
ex# = ex# - 2 * midx#: Next ey#
Else
ex# = ax# + lsope# * (ay# - Round(ay#) + 1.5): rex% = Round(ex#): mp5! = rex% - 0.5
zsl! = mp5! - midx#: pp5! = mp5! + 1: tri# = pp5! - lwrun#: trz = pp5! - lsope#
For ey# = Round(ay#) - 1.5 To Round(by#) + 1.5 Step -1
If ex# > tri# Then
Call DrawPixel(rex%, Int(ey#), gs(one!))
Else
If ex# > trz Then
Call DrawPixel(rex%, Int(ey#), gs(255 * (1 + slope# * sr(Int((pp5! - ex#) * 128)))))
Else: Call DrawPixel(rex%, Int(ey#), gs(255 * (ex# - zsl!))): End If
End If
If ex# > trz Then
tri# = tri# + 1: trz = trz + 1: pp5! = pp5! + 1
rex% = rex% + 1: zsl! = zsl! + 1: End If
ex# = ex# + lsope#: Next ey#
ex# = cx# - lsope# * (Round(cy#) + 1.5 - cy#): rex% = Round(ex#): mp5! = rex% - 0.5
tri# = mp5! + lwrun#: trz = mp5! + lsope#: zsl! = mp5! + 1 + midx#
For ey# = Round(cy#) + 1.5 To Round(dy#) - 1.5 Step 1
If ex# > tri# Then
If ex# < trz Then
Call DrawPixel(rex%, Int(ey# + 1), gs(255 * (1 + slope * sr(Int((ex# - mp5!) * 128)))))
Else: Call DrawPixel(rex%, Int(ey# + 1), gs(255 * (zsl! - ex#))): End If
End If
If ex# < trz Then
tri# = tri# - 1: trz = trz - 1: zsl! = zsl! - 1
rex% = rex% - 1: mp5! = mp5! - 1: End If
ex# = ex# - lsope#: Next ey#
ey# = by# - slope# * (bx# - Round(bx#) + 2.5)
For ex# = Round(bx#) - 2.5 To Round(ax#) + 0.5 Step -1
rey% = Round(ey#)
Call DrawPixel(Int(ex# + 1), rey%, gs(255 * (lsope# * sr(Int((ey# - rey% + 0.5) * 128)))))
ey# = ey# - slope#: Next ex#
ey# = dy# + slope# * (Round(dx#) + 1.5 - dx#)
For ex# = Round(dx#) + 1.5 To Round(cx#) - 0.5 Step 1
rey% = Round(ey#)
Call DrawPixel(Int(ex#), rey%, gs(255 * (lsope# * sr(Int((rey% + 0.5 - ey#) * 128)))))
ey# = ey# + slope#: Next ex#
End If
End If
Else
If epy! = spy! Then
rey% = Round(ay#): a! = ay# - rey% + 0.5
For ex# = Round(ax#) + 1.5 To Round(bx#) - 0.5
Call DrawPixel(Int(ex#), rey%, gs(255 * a!))
Call DrawPixel(Int(ex#), rey% - 1, 1 - gs(255 * a!))
Next ex#
Else
If epx! = spx! Then
rex% = Round(ax#): a! = ax# - rex% + 0.5
For ey# = Round(ay#) - 0.5 To Round(by) + 1.5 Step st
Call DrawPixel(rex%, Int(ey#), gs(255 * a!))
Call DrawPixel(rex% - 1, Int(ey#), 1 - gs(255 * a!))
Next ey#: End If
End If
End If
End Sub
Z.
Zaei
Oct 10th, 2002, 10:53 AM
And...
Private Sub DrawPixel(ByVal X As Long, ByVal Y As Long, _
ByVal Alpha As Single)
Dim TempColor As Long
Dim R2 As Long, G2 As Long, B2 As Long
'Get the color of the original pixel
TempColor = GetPixel(picBack.hdc, X, Y)
'Extract each one of the RGB values of the original pixel
'(don't waste your time trying to understand it :) )
R2 = TempColor And 255
G2 = (TempColor And 65535) \ 256
B2 = (TempColor And 16777215) \ 65536
'Add the original RGB values to the particle's RGB values
R2 = R2 + PixelR * Alpha
G2 = G2 + PixelG * Alpha
B2 = B2 + PixelB * Alpha
'Check if they're not above 255
If R2 > 255 Then R2 = 255
If G2 > 255 Then G2 = 255
If B2 > 255 Then B2 = 255
'Draw the pixel
SetPixelV picBack.hdc, X, Y, RGB(R2, G2, B2)
End Sub
Both functions ripped from Jotaf's sparks tutorial, which ripped the line function from somewhere else.
Z.
dafhi
Oct 10th, 2002, 11:21 AM
now that I see it, I understand that calling Drawpixel, while has rendering option advantage, (you can put a select case around like this
Select case PaintMode
Case 1 'normal
'Add the original RGB values to the particle's RGB values
R2 = R2 + PixelR * Alpha
G2 = G2 + PixelG * Alpha
B2 = B2 + PixelB * Alpha
Case 2 'luminescent look .. byte represents line or point intensity
r2 = r2 + (Byte / 255) * Abs(r2& - pixelr) ^ 0.85
g2 ..
)
is not real fast.
dafhi
Oct 10th, 2002, 12:18 PM
cyborg, if you can compute floating points along the curve, find a way to space the points so that single Aa pixels along a trail will look like an Aa curve:
Private Sub AaUnit(x1 As Single, y1 As Single)
Dim ax!, bx!
Dim ay!, by!
Dim RX1&, RY1&
Dim RX2&, RY2&
Dim xp5!
Dim l1!, l2!
Dim l3!, l4!
Dim Alpha As Byte
ax = x1 - 0.5
ay = y1 - 0.5
bx = ax + 1
by = ay + 1
RX1 = ax
RX2 = RX1 + 1
xp5 = RX1 + 0.5
RY1 = ay
RY2 = by
l1 = RY1 + 0.5 - ay
l2 = 256 * (xp5 - ax) - xp5 + ax
l3 = 255 - l2
l4 = by - RY2 + 0.5
Alpha = l1 * l2
PSet (RX1, RY1), RGB(Alpha, Alpha, Alpha)
Alpha = l1 * l3
PSet (RX2, RY1), RGB(Alpha, Alpha, Alpha)
Alpha = l4 * l2
PSet (RX1, RY2), RGB(Alpha, Alpha, Alpha)
Alpha = l4 * l3
PSet (RX2, RY2), RGB(Alpha, Alpha, Alpha)
End Sub
dafhi
Oct 10th, 2002, 01:10 PM
here is a version that will show you alpha-blended result
my browser doesn't space pasted text correctly so I will attach a file
dafhi
Oct 10th, 2002, 01:17 PM
alpha-blended AaUnit.txt
cyborg
Oct 13th, 2002, 07:44 PM
ok...
i tried the aaunit thing and it looked really good! :)
theres only one problem!
it uses Pset and Point and i want to change it to setpixelv and getpixel, but then it does not get AA-ed!
i change these lines:
BGR2 = Form1.Picture1.Point(RX1, RY1)
'and
Form1.Picture1.PSet (RX1, RY1), RGB(Red, Green, Blue)
'to
GetPixel Form1.Picture1.hdc, RX1, RY1
'and
SetPixelV Form1.Picture1.hdc, RX1, RY1, RGB(Red, Green, Blue)
What wrong?
Heres two pics that shows how it looks.
Here's the one with Pset and Point:
cyborg
Oct 13th, 2002, 07:44 PM
and here's the one with set/getpixel
cyborg
Oct 13th, 2002, 08:03 PM
i think i know whats wrong now :p
for got bgr2 = before getpixel
lol
cyborg
Oct 13th, 2002, 08:07 PM
but there are still some strange things!
if i change some things in the aaunit code and then change them back, it doesnt look the same as before!
but if i copy the original code back again, it looks good again!
and im 100% sure i changed everything back again!
thats really strange!
cyborg
Oct 13th, 2002, 08:13 PM
oooooh! im an idiot!!!
forget the last things i said!
i found out whats wrong!
cyborg
Oct 13th, 2002, 08:54 PM
here's the prog with AA
dafhi
Oct 14th, 2002, 08:05 AM
looks good
dafhi
Oct 14th, 2002, 08:51 AM
i like this program.
dafhi
Oct 14th, 2002, 08:55 AM
regarding thick lines, draw regular, then outline with Aa to improve speed
cyborg
Oct 14th, 2002, 03:17 PM
ok...i'll try that...
thanks for your help :)
cyborg
Oct 16th, 2002, 12:15 AM
im currently making a frame interpolator for the prog...
so it's possible to animate it now!
cyborg
Oct 16th, 2002, 01:23 AM
here's how it looks animated :)
cyborg
Oct 17th, 2002, 01:56 AM
WOHOO! :)
i've made a new scroll and a bar that shows animation keys!
looks really nice imo :) :) :)
try it and give me some comments!
btw. the animations are not 100% bug-free
animate it forward....i mean for example: do not animate frame 100 and the go back to animate frame 10.....that doesnt work yet
but otherwise it work good :p
cyborg
Oct 17th, 2002, 02:11 AM
heres an animation from it!
dafhi
Oct 18th, 2002, 09:13 AM
good stuff
cyborg
Oct 21st, 2002, 09:26 AM
thx
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.