All non-windows specific procedures for drawing lines in the forum which work also for printing have some disadvantages (very slow, not working for all angles or using the faulty circle command etc.)
Code: Select all
Procedure thickLineXY(start_x,start_y,end_x,end_y,thickness,whatcolor)
thickness>>1
err_x=0
err_y=0
inc_x=0
inc_y=0
delta_x=end_x - start_x;
delta_y=end_y - start_y;
If (delta_x>0)
inc_x=1
ElseIf (delta_x=0)
inc_x=0
Else
inc_x=-1
EndIf
If (delta_y>0)
inc_y=1
ElseIf (delta_y=0)
inc_y=0
Else
inc_y=-1
EndIf
delta_x=Abs(delta_x);
delta_y=Abs(delta_y);
If (delta_x>delta_y)
distance=delta_x;
Else
distance=delta_y;
EndIf
For xyz=0 To distance+1 Step 1
; modified to place a circle at the pixel location to get a thick line
;Plot(start_x,start_y,whatcolor)
Circle(start_x,start_y,thickness,whatcolor)
err_x=err_x + delta_x
err_y=err_y + delta_y
If (err_x>distance)
err_x=err_x - distance
start_x=start_x + inc_x
EndIf
If (err_y>distance)
err_y=err_y - distance
start_y=start_y +inc_y
EndIf
Next
EndProcedure
Procedure ClipLine(x1.w, y1.w, x2.w, y2.w, color,thickness.w)
; Draw line here with stupid PB Line command syntax
w=x2 - x1
h=y2 - y1
If wh
w=w+1
Else
h=h+1
If w=h
w=w+1
EndIf
EndIf
extra=0
For i.w=1 To thickness
If w>h
y1=y1+extra
Else
x1=x1+extra
EndIf
Line(x1, y1, w, h,color)
If extra<0
extra=extra-1
Else
extra=extra+1
EndIf
extra=-extra
Next
EndProcedure
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 NormalL(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)
Plot(X + n * SignX, Y + nn * SignY, ColorBlending(Color, Color_Found, Application))
Else
Plot(X + n * SignX, Y + nn * SignY, Color)
EndIf
EndIf
EndIf
Next
Next
EndProcedure
Procedure LineAA(X, Y, Width, Hight, Color, Thickness=1)
Protected SensX, SensY, n, nn, Epaisseur.f, x2.f, y2.f, Couleur_Fond.l, Application.f, Distance.f
; On mets la droite toujours dans le même sens pour l'analyse
; La sauvegarde du sens permettra de dessiner la droite ensuite dans le bon sens
If Width >= 0
SensX=1
Else
SensX=-1
Width=- Width
EndIf
If Hight >= 0
SensY=1
Else
SensY=-1
Hight=- Hight
EndIf
; Demi épaisseur de la ligne
Epaisseur.f=Thickness / 2
; calcul pour le changement de repère qui permet de connaitre l'épaisseur du trait et de gérer l'AA
Distance.f=Sqr(Width * Width + Hight * Hight)
CosAngle.f=Width / Distance
SinAngle.f=-Sin(ACos(CosAngle))
; Dessin de la ligne
For n=-Thickness To Width + Thickness
For nn=-Thickness To Hight + Thickness
; changement de base
; les y représentent l'épaisseur de la ligne
x2=n * CosAngle - nn * SinAngle
y2=Abs(n * SinAngle + nn * CosAngle)
If y2 <= Epaisseur + 0.5
Application= 0.5 + Epaisseur - y2
If Application>1
Application=1
EndIf
If x2>-1 And x2<Distance + 1
If x2<0
Application *(1 + x2)
ElseIf x2>Distance
Application *(1 - x2 + Distance)
EndIf
Else
Application=0
EndIf
If Application>0
If Application<1
Couleur_Fond=Point(X + n * SensX, Y + nn * SensY)
Plot(X + n * SensX, Y + nn * SensY, ColorBlending(Color, Couleur_Fond, Application))
Else
Plot(X + n * SensX, Y + nn * SensY, Color)
EndIf
EndIf
EndIf
Next
Next
EndProcedure
OpenWindow(0, 0, 0, 500, 500, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
CreateImage(0, 500, 500)
StartDrawing(ImageOutput(0))
#repeat=99
#angle=35
For i=0 To 3
t=ElapsedMilliseconds()
For m=0 To #repeat
p=0
For n=0 To #angle
If n&3=0 : p+1 : EndIf
Select i
Case 0
ClipLine(120,120,120+Sin(n*#PI/#angle*2)*100,120+Cos(n*#PI/#angle*2)*100,#Red,p); 1s
Case 1
thickLineXY(350,120,350+Sin(n*#PI/#angle*2)*100,120+Cos(n*#PI/#angle*2)*100,p,#Red); 15s
Case 2
NormalL(120,350,120+Sin(n*#PI/#angle*2)*100,350+Cos(n*#PI/#angle*2)*100,#Red,p); 15s
Case 3
LineAA(350,350,Sin(n*#PI/#angle*2)*100,Cos(n*#PI/#angle*2)*100,#Red,p); 15s
EndSelect
Next n
Next m
t-ElapsedMilliseconds()
Select i
Case 0
DrawText(200,30,Str(-t))
Case 1
DrawText(430,30,Str(-t))
Case 2
DrawText(200,240,Str(-t))
Case 3
DrawText(430,240,Str(-t))
EndSelect
Next i
StopDrawing()
ImageGadget(0, 0, 0, 300, 300, ImageID(0))
Repeat
Event=WaitWindowEvent()
Until Event=#PB_Event_CloseWindow