# PureBasic Forum

 It is currently Fri May 24, 2019 4:34 pm

 All times are UTC + 1 hour

 Page 1 of 1 [ 8 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: Math and vector graphicsPosted: Sat Nov 10, 2018 8:49 am

Joined: Thu Feb 09, 2006 11:27 pm
Posts: 2417
Would need some help again, I'd like to do rounded rectangles with light and shadow effect which works fine under simple conditions. But when using narrow boxes, everything gets scrambled... (I also want to implement a drop shadow which is even more complicate)

Here's an example which uses extra a large radius and wide light/shadow stripes to demonstrate the issues. Anyone good in math do create an universally working solution?

Code:
Procedure Min(a,b)
If a<b
ProcedureReturn a
Else
ProcedureReturn b
EndIf
EndProcedure

EndIf

ClosePath()

EndProcedure

Protected t1.d,t2.d,t3.d,t4.d,t5.d

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

MovePathCursor(x,y+r,flags)

ClosePath()

EndProcedure

Protected ro.d
Protected t1.d,t2.d,t3.d,t4.d,t5.d

ro=Min(Min(r,h/2),w/2)

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

r=ro
Debug ro

MovePathCursor(x+w,y+h-r,flags)

ClosePath()

EndProcedure

VectorSourceColor(\$a0000000|col)
FillPath(#PB_Path_Preserve)
VectorSourceColor(\$60000000)
StrokePath(1)

VectorSourceColor(\$40ffffff)
FillPath()
FillPath()
VectorSourceColor(\$20000000)
FillPath()
FillPath()

; Debug "Data.i "+Str(boxnr)+", "+Str(x)+","+Str(y)+", "+Str(w)+","+Str(h)+"; "+Str(size)

EndProcedure
Procedure show()

Protected i

StartVectorDrawing(CanvasVectorOutput(0))
VectorSourceColor(\$Ff000000|#White)
FillPath()

boxs(400,100,300,100,90,\$9AF0B8)
boxs(500,250,100,300,90,\$9AF0B8,20)

StopVectorDrawing()

EndProcedure

Procedure main()

#X=800
#Y=600

OpenWindow(0,0,0,#X,#Y,"")

show()

Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #WM_CHAR
End
EndSelect
ForEver

EndProcedure
main()

Top

 Post subject: Re: Math and vector graphicsPosted: Sat Nov 10, 2018 11:38 am
 User

Joined: Thu Jul 09, 2015 9:07 am
Posts: 71
Hi,

my brush functions can also be used with a vectordrawing path
Doesn't that suit you?
https://www.purebasic.fr/french/viewtopic.php?f=6&t=16385

Top

 Post subject: Re: Math and vector graphicsPosted: Sat Nov 10, 2018 12:57 pm

Joined: Thu Feb 09, 2006 11:27 pm
Posts: 2417
I like your routines, but I believe the functions are only producing perfect results when drawing an opaque layer at the top. Give me a hint if this is correct (I only made a quick test replacing all occurrences of \$FF by \$80...

I need transparent shapes, maybe the following example makes this a little bit clearer:
Code:
Procedure Min(a,b)
If a<b
ProcedureReturn a
Else
ProcedureReturn b
EndIf
EndProcedure

EndIf

ClosePath()

EndProcedure

Protected t1.d,t2.d,t3.d,t4.d,t5.d

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

MovePathCursor(x,y+r,flags)

ClosePath()

EndProcedure

Protected ro.d
Protected t1.d,t2.d,t3.d,t4.d,t5.d

ro=Min(Min(r,h/2),w/2)

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

r=ro
Debug ro

MovePathCursor(x+w,y+h-r,flags)

ClosePath()

EndProcedure

VectorSourceColor(\$a0000000|col)
FillPath(#PB_Path_Preserve)
VectorSourceColor(\$60000000)
StrokePath(1)

VectorSourceColor(\$40ffffff)
FillPath()
FillPath()
VectorSourceColor(\$20000000)
FillPath()
FillPath()

; Debug "Data.i "+Str(boxnr)+", "+Str(x)+","+Str(y)+", "+Str(w)+","+Str(h)+"; "+Str(size)

EndProcedure
Procedure show()

Protected i

StartVectorDrawing(CanvasVectorOutput(0))
VectorSourceColor(\$Ff000000|#White)
FillPath()

VectorSourceColor(\$400000f0)
FillPath()

boxs(400,100,300,100,90,\$9AF0B8)
boxs(500,250,100,300,90,\$9AF0B8,20)

StopVectorDrawing()

EndProcedure

Procedure main()

#X=800
#Y=600

OpenWindow(0,0,0,#X,#Y,"")

show()

Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #WM_CHAR
End
EndSelect
ForEver

EndProcedure
main()

And that's what I am able to produce with your code:
Code:
Macro doevents
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
EndMacro
Macro VFill(c,flag=#PB_Path_Default)
VectorSourceColor(\$20000000|(c&\$FFFFFF))
FillPath(flag)
EndMacro
Macro vcolor(c)
VectorSourceColor(c)
EndMacro

Procedure SortIdx(Array t.l(1),Array idx.l(1),deb=0, fin=-1) ;<= met dans le tableau idx() la position des element trié du tableau t()

Protected min,i,j,v,idmin
If fin=-1: fin=ArraySize(t()):EndIf
Dim idx(fin)
For i=deb To fin:idx(i)=i:Next
For i=deb To fin
min=\$7fffffff
For j=i To fin
v=t(idx(j))
If v<min:min=v:idmin=j:EndIf
Next
Swap idx(i),idx(idmin)
Next
EndProcedure
Procedure initIF(image,centerX.w=-1,centerY.w=-1)
;image : numero de l'image
;centerx/y : definit le centre de l'image
Structure IFsij
i.b
j.b
EndStructure

Protected i,j,n,di,dj
Protected idx=ImageWidth (image)
Protected idy=ImageHeight(image)
Protected Dim IFdis.l(idx * idy-1)
Global IFcenterx
If centerX=-1:IFcenterx=idx/2:Else:IFcenterx=centerx:EndIf
Global IFcenterY
If centery=-1:IFcentery=idy/2:Else:IFcentery=centery:EndIf
Global Dim IFidx.l(idx * idy-1)
Global Dim IFbmp.l(idx-1,idy-1)
Global Dim IFpos.IFsij(idx * idy-1)

StartDrawing(ImageOutput(image))
DrawingMode(#PB_2DDrawing_AllChannels)
For j=0 To idy-1
For i=0 To idx-1
IFbmp(i,j)=Point(i,j)
IFpos(n)\i=i:di=i-IFcenterx
IFpos(n)\j=j:dj=j-IFcentery
;IFdis(n)=di*di+dj*dj
IFdis(n)=Abs(di)+Abs(dj)
n+1
Next
Next
StopDrawing()
sortidx(IFdis(),IFidx())
EndProcedure
Procedure FillPathBrush(image,centerX.w=-1,centerY.w=-1)
initIF(image,centerX,centerY)
Protected s.s=PathSegments()
Protected n,nn=ArraySize(IFidx())
ResetPath()
For n=0 To nn
With IFpos(IFidx(nn-n))
If Alpha(IFbmp(\i,\j))
MovePathCursor(\i-ifcenterX+1,\j-ifcentery+1)
Vfill(IFbmp(\i,\j))
EndIf
EndWith
Next
EndProcedure

Procedure exemple()
EnableExplicit
Protected i,j,n, a.f,y, idx=800,idy=600
For n=0 To 7
CreateImage(10+n,16,16,32,#PB_Image_Transparent)
StartVectorDrawing(ImageVectorOutput(10+n))
Select n
Case 0
EndSelect
StopVectorDrawing()
Next

CreateImage(0,idx,idy,32,#White)

StartVectorDrawing(ImageVectorOutput(0))
VectorSourceColor(\$6000ff00)
FillPath()

y=i*72+10
MovePathCursor(0,30+y)
;DrawVectorImage(ImageID(10+i))
FillPathBrush(10+i)

StopVectorDrawing()

OpenWindow(0, 0, 0, idx, idy, "VectorDrawing-Brush", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
doevents
EndProcedure

exemple()

Top

 Post subject: Re: Math and vector graphicsPosted: Sat Nov 10, 2018 1:54 pm

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 964
Location: right here
I played a bit with this.
Code:
Procedure show()
[...]
; some random background
For i=0 To 1000
VectorSourceColor(RGBA(Random(255),Random(255),Random(255),Random(20)))
FillPath()
Next
[...]

Code:

Protected alpha.f = 20
Protected size = 20
Protected offset.f = 5
Protected color = \$60000000

For i=1 To size
VectorSourceColor(RGBA(Red(color), Green(color), Blue(color), alpha*((size-i)/size)))
StrokePath(1)
Next

[...]

I'm drawing the round-box outline multiple times with increasing size and decreasing alpha. I used an offset so the shadow is larger on the bottom-right than it is on the top-left. Unfortunately it becomes also denser/darker in the top-left, which looks counterintuitive. If you use an offset of size/2 it looks ok though. Maybe that's a start

Code:
Procedure Min(a,b)
If a<b
ProcedureReturn a
Else
ProcedureReturn b
EndIf
EndProcedure

EndIf

ClosePath()

EndProcedure

Protected t1.d,t2.d,t3.d,t4.d,t5.d

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

MovePathCursor(x,y+r,flags)

ClosePath()

EndProcedure

Protected ro.d
Protected t1.d,t2.d,t3.d,t4.d,t5.d

ro=Min(Min(r,h/2),w/2)

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

r=ro
Debug ro

MovePathCursor(x+w,y+h-r,flags)

ClosePath()

EndProcedure

Protected alpha.f = 20
Protected size = 20
Protected offset.f = 5
Protected color = \$60000000

For i=1 To size
VectorSourceColor(RGBA(Red(color), Green(color), Blue(color), alpha*((size-i)/size)))
StrokePath(1)
Next

VectorSourceColor(\$a0000000|col)
FillPath(#PB_Path_Preserve)
VectorSourceColor(\$60000000)
StrokePath(1)

VectorSourceColor(\$40ffffff)
FillPath()
FillPath()
VectorSourceColor(\$20000000)
FillPath()
FillPath()

; Debug "Data.i "+Str(boxnr)+", "+Str(x)+","+Str(y)+", "+Str(w)+","+Str(h)+"; "+Str(size)

EndProcedure
Procedure show()

Protected i

StartVectorDrawing(CanvasVectorOutput(0))
VectorSourceColor(\$Ff000000|#White)
FillPath()

; some random background
For i=0 To 1000
VectorSourceColor(RGBA(Random(255),Random(255),Random(255),Random(20)))
FillPath()
Next

boxs(400,100,300,100,90,\$9AF0B8)
boxs(500,250,100,300,90,\$9AF0B8,20)

StopVectorDrawing()

EndProcedure

Procedure main()

#X=800
#Y=600

OpenWindow(0,0,0,#X,#Y,"")

show()

Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
;       Case #WM_CHAR
;          End
EndSelect
ForEver

EndProcedure
main()

Top

 Post subject: Re: Math and vector graphicsPosted: Sat Nov 10, 2018 4:36 pm

Joined: Thu Feb 09, 2006 11:27 pm
Posts: 2417
#Null, interestng approach, will also play around with your code now...

Tried to do clipping but that's not the best function in PB because it does not do alpha or antialiazing...

Code:
Procedure Min(a,b)
If a<b
ProcedureReturn a
Else
ProcedureReturn b
EndIf
EndProcedure
Macro StartClipping()
SaveVectorState()
ClipPath()
EndMacro
Macro StopClipping()
RestoreVectorState()
EndMacro

EndIf

ClosePath()

EndProcedure

Protected t1.d,t2.d,t3.d,t4.d,t5.d

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

MovePathCursor(x,y+r,flags)

ClosePath()

EndProcedure

Protected ro.d
Protected t1.d,t2.d,t3.d,t4.d,t5.d

ro=Min(Min(r,h/2),w/2)

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

r=ro
Debug ro

MovePathCursor(x+w,y+h-r,flags)

ClosePath()

EndProcedure

Protected i
StartClipping()

For i=1 To size
VectorSourceColor(RGBA(Red(color), Green(color), Blue(color), alpha*((size-i)/size)))
;StrokePath(1)
FillPath()
Next
StopClipping()

EndProcedure

VectorSourceColor(\$a0000000|col)
FillPath(#PB_Path_Preserve)
VectorSourceColor(\$60000000)
StrokePath(1)

If 0
VectorSourceColor(\$40ffffff)
FillPath()
FillPath()
VectorSourceColor(\$20000000)
FillPath()
FillPath()
EndIf

; Debug "Data.i "+Str(boxnr)+", "+Str(x)+","+Str(y)+", "+Str(w)+","+Str(h)+"; "+Str(size)

EndProcedure
Procedure show()

Protected i

StartVectorDrawing(CanvasVectorOutput(0))
VectorSourceColor(\$Ff000000|#White)
FillPath()

; some random background
If 0
For i=0 To 1000
VectorSourceColor(RGBA(Random(255),Random(255),Random(255),Random(20)))
FillPath()
Next
EndIf

boxs(400,100,300,100,90,\$9AF0B8)
boxs(500,250,100,300,90,\$9AF0B8,20)

StopVectorDrawing()

EndProcedure

Procedure main()

#X=800
#Y=600

OpenWindow(0,0,0,#X,#Y,"")

show()

Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
;       Case #WM_CHAR
;          End
EndSelect
ForEver

EndProcedure
main()

Top

 Post subject: Re: Math and vector graphicsPosted: Sat Nov 10, 2018 5:56 pm

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 964
Location: right here
Looks pretty good
I think you could also use layers (BeginVectorLayer()). Overdrawing the shadow with the actual button by drawing the button completely opaque on top of the shadow, but both within a layer with its own transparency to blend everything with the background.

<edit>That would probably be more difficult if your buttons are drawn with multiple transparent parts on top of each other. But you could partially clear the shadow by drawing a opaque button background first. That would clear only the shadow within the layer and can be blended with the underlying background later.
But with the clipping it already looks fine anyway.

Top

 Post subject: Re: Math and vector graphicsPosted: Sat Nov 10, 2018 6:44 pm

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 964
Location: right here
Code:
If r>h/2 : r=h/2 : EndIf
If r>w/2 : r=w/2 : EndIf
..that seems to solve some of the issues.

<edit>

Top

 Post subject: Re: Math and vector graphicsPosted: Sat Nov 10, 2018 8:01 pm

Joined: Thu Feb 09, 2006 11:27 pm
Posts: 2417
Some moments later...

Good idea about layers, which would be even more useful when an UnfillPath (Unstroke) function would also exist to allow erasing content from the layer (as said, clipping is not ideal because it's border are calculated pixel wise).

There's still a kind of light aura arround the buttons (could be seen best on the lower blue box), but the result is not that bad...

Code:
Procedure Min(a,b)
If a<b
ProcedureReturn a
Else
ProcedureReturn b
EndIf
EndProcedure
Macro StartClipping()
SaveVectorState()
ClipPath()
EndMacro
Macro StopClipping()
RestoreVectorState()
EndMacro

EndIf

ClosePath()

EndProcedure

Protected t1.d,t2.d,t3.d,t4.d,t5.d

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

MovePathCursor(x,y+r,flags)

ClosePath()

EndProcedure

Protected ro.d
Protected t1.d,t2.d,t3.d,t4.d,t5.d

ro=Min(Min(r,h/2),w/2)

t1=Cos(angle*#PI/180);   1-89°
t2=Sin(angle*#PI/180)
t3=r*t1
t4=r*t2
t5=2*r-t4

r=ro
Debug ro

MovePathCursor(x+w,y+h-r,flags)

ClosePath()

EndProcedure

Protected i
StartClipping()

For i=1 To size
VectorSourceColor(RGBA(Red(color), Green(color), Blue(color), Alpha/size))
FillPath()
Next
StopClipping()

EndProcedure

BeginVectorLayer(min(alpha,255))

VectorSourceColor(darkness<<24)
FillPath()
Next i

; Filled Button
VectorSourceColor(\$ff000000|col)
FillPath()

; Erasing area...
;VectorSourceColor(\$fffffffff)
;FillPath()

VectorSourceColor(\$40ffffff)
FillPath()
FillPath()
VectorSourceColor(\$20000000)
FillPath()
FillPath()

; Button Border
VectorSourceColor(\$60000000)
StrokePath(1)

EndVectorLayer()

EndProcedure
Procedure show()

Protected i

StartVectorDrawing(CanvasVectorOutput(0))
VectorSourceColor(\$Ff000000|#White)
FillPath()

; some random background
For i=0 To 100
VectorSourceColor(RGBA(Random(255),Random(255),Random(255),Random(40)))
FillPath()
Next

boxs(400,100,300,100,90,\$9AF0B8,120,10)
boxs(500,250,100,300,90,\$9AF0B8,180,20)

StopVectorDrawing()

EndProcedure

Procedure main()

#X=800
#Y=600

OpenWindow(0,0,0,#X,#Y,"")

show()

Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
;       Case #WM_CHAR
;          End
EndSelect
ForEver

EndProcedure
main()

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 8 posts ]

 All times are UTC + 1 hour

#### Who is online

Users browsing this forum: No registered users and 7 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forum

Search for:
 Jump to:  Select a forum ------------------ PureBasic    Coding Questions    Game Programming    3D Programming    Assembly Programming    The PureBasic Editor    The PureBasic Form Designer    General Discussion    Feature Requests and Wishlists    Tricks 'n' Tips Bug Reports    Bugs - Windows    Bugs - Linux    Bugs - Mac OSX    Bugs - Documentation OS Specific    AmigaOS    Linux    Windows    Mac OSX Miscellaneous    Announcement    Off Topic Showcase    Applications - Feedback and Discussion    PureFORM & JaPBe    TailBite