Anti-Aliased Free line drawing [Windows]

Share your advanced PureBasic knowledge/code with the community.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Anti-Aliased Free line drawing [Windows]

Post by RASHAD »

Hi

Code: Select all

Global Thickness,Color

ProcedureDLL.l ColorBlending(Color1.l, Color2.l, Blend.f)
  Protected Red, Green, Blue, Red2, Green2, Blue2
 
  Red = Color1 & $FF
  Green = Color1 >> 8 & $FF
  Blue = Color1 >> 16
  Red2 = Color2 & $FF
  Green2 = Color2 >> 8 & $FF
  Blue2 = Color2 >> 16
 
  Red = Red * Blend + Red2 * (1-Blend)
  Green = Green * Blend + Green2 * (1-Blend)
  Blue = Blue * Blend + Blue2 * (1-Blend)
 
  ProcedureReturn (Red | Green <<8 | Blue << 16)
EndProcedure

Procedure AAline(X,Y, x3, y3, Color, Thickness = 1)
  Width = x3-X
  Hight = y3-Y
  Protected SignX, SignY, n, nn, Thick.f, x2.f, y2.f, Color_Found.l, Application.f, Hypo.f
 
  If Width >= 0
    SignX = 1
  Else
    SignX = -1
    Width = - Width
  EndIf
  If Hight >= 0
    SignY = 1
  Else
    SignY = -1
    Hight = - Hight
  EndIf 
 
  Thick.f = Thickness / 2
 
  Hypo.f = Sqr(Width * Width + Hight * Hight)
  CosPhi.f = Width / Hypo
  SinPhi.f = -Sin(ACos(CosPhi))
 
 
  For n = -Thickness To Width + Thickness
    For nn = -Thickness To Hight + Thickness

      x2 = n * CosPhi - nn * SinPhi
      y2 = Abs(n * SinPhi + nn * CosPhi)
     
      If y2 <= Thick + 0.5
        Application =  0.5 + Thick - y2
        If Application > 1
          Application = 1
        EndIf
        If x2 > -1 And x2 < Hypo + 1
          If x2 < 0
            Application * (1 + x2)
          ElseIf x2 > Hypo
            Application * (1 - x2 + Hypo)
          EndIf
        Else
          Application = 0
        EndIf
        If Application > 0
          If Application < 1
            Color_Found = Point(X + n * SignX, Y + nn * SignY)
            If Thickness < 6
              Plot(X + n * SignX, Y + nn * SignY, ColorBlending(Color, Color_Found, Application))
            Else
              Circle(X + n * SignX, Y + nn * SignY,Thickness/2, ColorBlending(Color, Color_Found, Application))
            EndIf
          Else
            If Thickness < 6
              Plot(X + n * SignX, Y + nn * SignY, Color)
            Else
              Circle(X + n * SignX, Y + nn * SignY,Thickness/2, Color)
            EndIf
          EndIf
        EndIf
      EndIf     
    Next
  Next
 
EndProcedure

Thickness = 20
Color = $FF0000

OpenWindow(0, 0, 0, 500, 500, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)

Repeat
  Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
            Quit = 1
            
      Case #WM_MOUSEMOVE
            If Flag = 1
              GetCursorPos_(p.POINT)
              ScreenToClient_(WindowID(0),p)
              If p\x > Thickness And p\x < (WindowWidth(0)-Thickness) And p\y > Thickness And p\y < (WindowHeight(0)-Thickness)          
                AAline(oldx,oldy,p\x,p\y,Color,Thickness)
              EndIf
            EndIf
            oldx=p\x
            oldy=p\y         
  
      Case #WM_LBUTTONDOWN            
            GetCursorPos_(p.POINT)
            ScreenToClient_(WindowID(0),p)            
            If p\x > Thickness And p\x < (WindowWidth(0)-Thickness) And p\y > Thickness And p\y < (WindowHeight(0)-Thickness)
              Flag = 1
              StartDrawing(WindowOutput(0))
              oldx=p\x
              oldy=p\y
            Else
              Flag = 0
              StopDrawing()
            EndIf
        
       Case #WM_LBUTTONUP
            If Flag = 1
              Flag = 0
              StopDrawing()
            EndIf
 
  EndSelect
 
Until Quit = 1
Edit : Fixed some bugs
Last edited by RASHAD on Fri Jul 03, 2015 2:40 am, edited 1 time in total.
Egypt my love
infratec
Always Here
Always Here
Posts: 7620
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Anti-Aliased Free line drawing [Windows]

Post by infratec »

Hi RASHAD,

nice work :!:

A few comments:

Why not WindowMouseX() and WindowMouseY() ?
Then it should be crossplatform.

And your demo have a problem:
If you place the mouse really at the top left corner and start... (With thickness > 1)
Point is outside the drawable area.

Bernd
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Anti-Aliased Free line drawing [Windows]

Post by RASHAD »

Hi Bernd

Previous post updated
I am not sure if using WindowMouseX() and WindowMouseY() will make the code cross - platform
Beside using such commands will need a lot of time used by the events loop
Egypt my love
Post Reply