How to draw a GraphicsPath with offsets?

Hi,

I need to draw a GraphicsPath (a polygon made with several appended lines), and the view may be scrolled (in other words, the polygon may be drawn at a different location).

My first attempt was to try with GraphicsPath.MoveToPoint OffsetX,OffsetY, but that doesn’t have any effect. I also tried GraphicsPath.Bounds.Offset OffsetX,OffsetY with the same result.
Since there doesn’t appear to have a way to retrieve the path’s components, I can’t loop thru them to change their location either. It looks like the only way is to re-create the shape every single time the user scrolls, which doesn’t sound practical to me.

Am I missing an existing solution?

Array point

examble Test

graphicspath-DX-Points-test-6.xojo_binary_project.zip (30.3 KB)

1 Like

Thanks for your reply.
So, in effect, you’re reconstructing the path each time something changes (which I mentioned as “not practical” in my original question, but perhaps my words were poorly chosen; I meant it looks weird to rebuild the path each time).

No way to move an existing path?

.Translate ?

If this method existed, it’d be the answer I’m looking for.
Thanks anyway.

He means Graphics.Translate. This lets you move all drawing, not just a single path.

2 Likes

https://documentation.xojo.com/api/graphics/graphics.html#graphics-translate

see also .savestate and .restorestate

.DrawObject could also be useful
https://documentation.xojo.com/api/graphics/graphics.html#graphics-drawobject

Graphics.Translate did the trick; thanks Markus!
Yet another language feature that even long-time users may not notice since introduced :sweat_smile:

3 Likes

hello arnaud
I can’t use graphics.translate properly in my desktop program
can you please show your programming code
enclosed is my test program

erstellelinienpath-test.xojo_binary_project.zip (35.1 KB)

All you need to do is to translate, draw, and translate back.
For example, with the issue I had for drawing a polygon (GraphicsPath) with an offset, the solution works like that:

Var DX,DY As Integer
DY=100 'Draw with an offset of 100 pixels vertically

g.Translate 0-DX,0-DY 'Change the graphics' origin point
g.FillPath ThePath 'Draw the polygon
g.DrawPath ThePath 'Draw the border
g.Translate DX,DY 'Restore the origin point

HTH

P.S.: I’m not sure what to do with the project you linked, sorry. It just draws nothing even after clicking and I’m not sure how you intended to use it.

The safer way to do this is with a SaveState and RestoreState:

Var DX,DY As Integer
DY=100 'Draw with an offset of 100 pixels vertically

g.SaveState 'Save the state of the graphics object
g.Translate 0-DX,0-DY 'Change the graphics' origin point
g.FillPath ThePath 'Draw the polygon
g.DrawPath ThePath 'Draw the border
g.RestoreState 'Restore the state of the graphics object

The reason Save/RestoreState are safer is that you can make all sorts of changes to the state - rotate, translate, skew, etc. - and know that all the changes will be rolled back 100% after you are done. You also don’t have to worry about backing out the changes in the correct order.

Additionally: in some graphics systems, it isn’t possible (or not as accurate) to reverse out a state change with its inverse action (i.e., g.Translate DX, DY followed by g.Translate -DX, -DY). This mostly applies to raw matrix transformations, which might not apply to Xojo. Still, it is best practice to save and restore.

AFAIK, which properties are covered by save&restore aren’t documented. It could very well be that only the most common ones are concerned.

1 Like

To my knowledge, the Graphics functions map directly to CoreGraphics on the Mac - so this reference should be useful:

Graphics libraries that support the notion of saving and restoring generally all work the same – it’s a concept borrowed from PostScript, the grandaddy of modern 2D imaging libraries including mac OS’s CoreGraphics. The idea of the saved state is that it encompasses every property that will affect future drawing, so things such as translation, rotation, line width, font, etc. It does not include pixels or vectors that have already been rendered.

Thank you for your answer
I now understand graphics.translate to some extent
but it is difficult with my over 100 elements with different sizes and angles
I will stick with my 2D elements, which I can rotate and change around the center as I like

I have added a few instructions to the example and changed something, I hope that it will now work on another computer

erstellelinienpath-testnew.xojo_binary_project.zip (40.0 KB)

I think there’s no reason to change from existing shapes to GraphicsPaths (except for the polygon which was deprecated some months ago).
In fact, I don’t agree to the deprecation of DrawPolygon and FillPolygon in favour of GraphicsPaths, because now we have, on one hand, the shapes version (ArcShape, CurveShape, RectShape, etc.) and, on another hand, the shape for polygons; obviously both groups have a distinct set of logic, so there are now more exceptions to the rules than with the deprecated way (with no apparent benefit).