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?
Printable View
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?
Find an antialiased line drawing function, and use that to draw the curve =).
Z.
were can i find that?
Google.
Z.
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?
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.
Z.Code: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
And...
Both functions ripped from Jotaf's sparks tutorial, which ripped the line function from somewhere else.Code: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
Z.
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.
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
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
alpha-blended AaUnit.txt
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:
VB Code:
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:
and here's the one with set/getpixel
i think i know whats wrong now :p
for got bgr2 = before getpixel
lol
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!
oooooh! im an idiot!!!
forget the last things i said!
i found out whats wrong!
here's the prog with AA
looks good
i like this program.
regarding thick lines, draw regular, then outline with Aa to improve speed
ok...i'll try that...
thanks for your help :)
im currently making a frame interpolator for the prog...
so it's possible to animate it now!
here's how it looks animated :)
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
heres an animation from it!
good stuff
thx