Nice examples, guys.
Does anyone have an example that zooms AND rotates AND moves along the X/Y axis?
Zoom an vector drawn image
Re: Zoom an vector drawn image
Win10, PB6.x, okayish CPU, onboard video card, fuzzy monitor (or is that my eyesight?)
"When the facts change, I change my mind" - John Maynard Keynes
"When the facts change, I change my mind" - John Maynard Keynes
-
- Addict
- Posts: 4777
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Zoom an vector drawn image
Here you go!Amundo wrote:Does anyone have an example that zooms AND rotates AND moves along the X/Y axis?

Besides rotating and moving, zooming now can also be done with the keyboard.
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
Last edited by Little John on Tue Apr 04, 2017 3:05 pm, edited 1 time in total.
-
- Addict
- Posts: 4777
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Zoom an vector drawn image
Here is another version, using the built-in vector commands TranslateCoordinates() and RotateCoordinates() for moving and rotating, respectively. For zooming, I didn't manage to use ScaleCoordinates() properly, since I want to use the center of the object as anchor point, not the upper left corner.
Now it doesn't make much sense anymore to write some parts of the code as separate procedures. However, I didn't change that, so that it's easier to compare this code with the previous one.
Now it doesn't make much sense anymore to write some parts of the code as separate procedures. However, I didn't change that, so that it's easier to compare this code with the previous one.
Code: Select all
; LJ 2017-04-04, <http://www.purebasic.fr/english/viewtopic.php?p=505463#p505463>
; 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
angle.d
offset.PointD
EndStructure
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
TranslateCoordinates(\offset\x, \offset\y)
RotateCoordinates(\center\x, \center\y, \angle)
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)
*obj\angle + rotation
DrawObject(canvas, *obj)
EndProcedure
Procedure MoveObject_Horizontal (canvas.i, *obj.Polygon, dx.d)
*obj\offset\x + dx
DrawObject(canvas, *obj)
EndProcedure
Procedure MoveObject_Vertical (canvas.i, *obj.Polygon, dy.d)
*obj\offset\y + dy
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
\angle = 0.0
\offset\x = 0.0
\offset\y = 0.0
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
Last edited by Little John on Tue Apr 04, 2017 3:07 pm, edited 1 time in total.
Re: Zoom an vector drawn image
Thanks for the comparison code Little John.
Small problem. Rotating the object completely does not arrive at its original angle? Small skew.

Small problem. Rotating the object completely does not arrive at its original angle? Small skew.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
-
- Addict
- Posts: 4777
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: Zoom an vector drawn image
Hello skywalk, many thanks for your bug report.
Obviously, choosing 0.1 radians (about 5.73 degrees) as step for rotating wasn't a good idea.

In both codes above, I've changed that now to 6.0 degrees, which should work fine (at least in theory).
Thanks again!
Obviously, choosing 0.1 radians (about 5.73 degrees) as step for rotating wasn't a good idea.


In both codes above, I've changed that now to 6.0 degrees, which should work fine (at least in theory).
Thanks again!
Re: Zoom an vector drawn image
Ah, makes sense now. I was thinking degrees(°).
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: Zoom an vector drawn image
LittleJohn, I can't thank you enough, I will use your code to move horizontally/vertically, which was the last piece I needed.
(I think I have the code to translate the coordinates necessary, but would have had to translate it for this situation).
Thanks a million for all your help!
Edit: Actually, I've completely lost the plot!! The only thing I need to fix is the zoom!
(I think I have the code to translate the coordinates necessary, but would have had to translate it for this situation).
Thanks a million for all your help!
Edit: Actually, I've completely lost the plot!! The only thing I need to fix is the zoom!
Win10, PB6.x, okayish CPU, onboard video card, fuzzy monitor (or is that my eyesight?)
"When the facts change, I change my mind" - John Maynard Keynes
"When the facts change, I change my mind" - John Maynard Keynes