Code: Select all
; LJ 2017-04-04, <http://www.purebasic.fr/english/viewtopic.php?p=505458#p505458>
; successfully tested with PB 5.60 (x64) on Windows 10
CompilerIf #PB_Compiler_Version < 550
MessageRequester("Error", "PureBasic version 5.50 or newer required because the new bounding box functions are used.")
CompilerElse
EnableExplicit
Structure PointD
x.d
y.d
EndStructure
Structure Polygon
Array p.PointD(0)
center.PointD
color.i
width.i
EndStructure
;-----------------------------------------------------------------------
Macro Rect2Polar_D (_x_, _y_)
; -- convert rectangular coordinates to polar coordinates
; in : _x_, _y_: rectangular coordinates
; out: corresponding distance
Sqr((_x_)*(_x_) + (_y_)*(_y_))
EndMacro
Macro Rect2Polar_A (_x_, _y_)
; -- convert rectangular coordinates to polar coordinates
; in : _x_, _y_: rectangular coordinates
; out: corresponding angle, expressed in rad;
; ]-Pi; +Pi]
ATan2(_x_, _y_)
EndMacro
;-----------------------------------------------------------------------
Macro Polar2Rect_X (_distance_, _angle_)
; -- convert polar coordinates to rectangular coordinates
; in : _distance_: must be >= 0
; _angle_ : expressed in rad
; out: corresponding x coordinate
((_distance_) * Cos(_angle_))
EndMacro
Macro Polar2Rect_Y (_distance_, _angle_)
; -- convert polar coordinates to rectangular coordinates
; in : _distance_: must be >= 0
; _angle_ : expressed in rad
; out: corresponding y coordinate
((_distance_) * Sin(_angle_))
EndMacro
;-----------------------------------------------------------------------
Procedure DrawObject (canvas.i, *obj.Polygon)
Protected.i i, last = ArraySize(*obj\p())
If StartVectorDrawing(CanvasVectorOutput(canvas))
; clear canvas
VectorSourceColor(RGBA(255, 255, 255, 255))
FillVectorOutput()
; draw object and get the center of its bounding box
With *obj
MovePathCursor(\p(0)\x, \p(0)\y)
For i = 1 To last
AddPathLine(\p(i)\x, \p(i)\y)
Next
ClosePath()
\center\x = PathBoundsX() + PathBoundsWidth()/2.0
\center\y = PathBoundsY() + PathBoundsHeight()/2.0
VectorSourceColor(\color)
StrokePath(\width)
EndWith
StopVectorDrawing()
EndIf
EndProcedure
Procedure ZoomObject (canvas.i, *obj.Polygon, factor.d)
Protected.i i, last = ArraySize(*obj\p())
With *obj
For i = 0 To last
\p(i)\x + factor * (\p(i)\x - \center\x)
\p(i)\y + factor * (\p(i)\y - \center\y)
Next
EndWith
DrawObject(canvas, *obj)
EndProcedure
Procedure RotateObject (canvas.i, *obj.Polygon, rotation.d)
Protected.i i, last = ArraySize(*obj\p())
Protected.d distance, angle
rotation = Radian(rotation)
With *obj
For i = 0 To last
distance = Rect2Polar_D(\p(i)\x - \center\x, \p(i)\y - \center\y)
angle = Rect2Polar_A(\p(i)\x - \center\x, \p(i)\y - \center\y)
\p(i)\x = \center\x + Polar2Rect_X(distance, angle + rotation)
\p(i)\y = \center\y + Polar2Rect_Y(distance, angle + rotation)
Next
EndWith
DrawObject(canvas, *obj)
EndProcedure
Procedure MoveObject_Horizontal (canvas.i, *obj.Polygon, dx.d)
Protected.i i, last = ArraySize(*obj\p())
With *obj
For i = 0 To last
\p(i)\x + dx
Next
EndWith
DrawObject(canvas, *obj)
EndProcedure
Procedure MoveObject_Vertical (canvas.i, *obj.Polygon, dy.d)
Protected.i i, last = ArraySize(*obj\p())
With *obj
For i = 0 To last
\p(i)\y + dy
Next
EndWith
DrawObject(canvas, *obj)
EndProcedure
;-======================================================================
; Windows
Enumeration
#WinMain
EndEnumeration
; Gadgets
Enumeration
#Canvas
EndEnumeration
Define obj.Polygon, dw.i, event.i
;-- Create a window with a canvas gadget
If OpenWindow(#WinMain, 0, 0, 400, 400, "Canvas demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0
MessageRequester("Fatal error", "Couldn't open main window.")
End
EndIf
CanvasGadget(#Canvas, 0, 0, 400, 400, #PB_Canvas_Keyboard)
SetActiveGadget(#Canvas) ; set the keyboard focus on the canvas gadget
;-- Define a polygon
With obj
Dim \p(4)
\p(0)\x = 100.0 : \p(0)\y = 250.0
\p(1)\x = 250.0 : \p(1)\y = 250.0
\p(2)\x = 250.0 : \p(2)\y = 170.0
\p(3)\x = 175.0 : \p(3)\y = 140.0
\p(4)\x = 100.0 : \p(4)\y = 170.0
\color = RGBA(255, 0, 0, 255)
\width = 2
EndWith
;-- Show the polygon
DrawObject(#Canvas, @obj)
;-- Process events
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
Select EventGadget()
Case #Canvas
Select EventType()
Case #PB_EventType_MouseWheel
;-- Zoom
dw = GetGadgetAttribute(#Canvas, #PB_Canvas_WheelDelta)
ZoomObject(#Canvas, @obj, 0.1*dw)
Case #PB_EventType_KeyDown
Select GetGadgetAttribute(#Canvas, #PB_Canvas_Key)
;-- Zoom
Case #PB_Shortcut_Add
ZoomObject(#Canvas, @obj, 0.1)
Case #PB_Shortcut_Subtract
ZoomObject(#Canvas, @obj, -0.1)
;-- Rotate (angle expressed in degrees)
Case #PB_Shortcut_PageDown
RotateObject(#Canvas, @obj, 6.0)
Case #PB_Shortcut_PageUp
RotateObject(#Canvas, @obj, -6.0)
;-- Move
Case #PB_Shortcut_Right
MoveObject_Horizontal(#Canvas, @obj, 3)
Case #PB_Shortcut_Left
MoveObject_Horizontal(#Canvas, @obj, -3)
Case #PB_Shortcut_Down
MoveObject_Vertical(#Canvas, @obj, 3)
Case #PB_Shortcut_Up
MoveObject_Vertical(#Canvas, @obj, -3)
EndSelect
EndSelect
EndSelect
EndIf
Until event = #PB_Event_CloseWindow
CompilerEndIf