Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python fu: Vector stroke scaling
How to scale a stroke and keep position at center.
red -- original stroke
blue -- after scaling using
stroke.scale(0.5, 0.5)

Attached Files Thumbnail(s)
You have to define the "center" of the stroke Smile Is it the center of the bounding box? The center of mass/centroid? or something else? Once you have determined that, you compute the center for the before/after/strokes, compute the delta vector, and shift the stroke accordingly.

Note: the API to translate a stroke (stroke:translate() or its PDB equivalent) only shifts an integer amount of pixels, which makes it unusable in most cases. So you just construct a new stroke by adding the corresponding delta to all coordinates (anchors and tangents). A nice trick is to use a "cycle" generator:

translatedCoords=[coord+next(offsets) for coord in sourceCoords]
translatedStroke = gimp.VectorsBezierStroke(targetPath,translatedCoords,closed)

But your 2nd image makes me think that you don't want a scaled stroke, but the stroke which is "parallel" to the outer one, which is a different thing. If you tell me what you are trying to do I can find a way to do it differently. If you are on 2.10 there is however an indirect way to have Gimp create that path for you.
I want something like grow/ shrink selection but for strokes. We specify how much to grow/ shrink.

Sorry for my BAD English.
(08-24-2018, 06:01 PM)awan Wrote: I want something like grow/ shrink selection but for strokes. We specify how much to grow/ shrink.

Sorry for my BAD English.

I guessed so Smile

So, the 2.10 technique, to get the path that is 10px inwards or outwards from your path:

- Stroke the path in line mode (new 2.10 API (*)) on a transparent layer, with a 20px width
- Alpha to selection: gimp_select_item(layer)
- Select>ToPath: plug_in_sel2path(image, drawable)
- That path has two strokes, one is inside, one is outside (how to tell: get the length, the shortest is inside)

(*) The new 2.10 API, the calls you'll have to use:
pdb.gimp_drawable_edit_stroke_item(drawable, path)
Your technique will works only if the path is inside the layer and the canvas.
Right... But you can always copy the path to a suitably big "background" image (no associated Display), do the thing, and copy the path back. By definition of Bézier curves, the path is completely within the rectangle defined by the min and max X and Y coordinates of its anchors or tangents.

Forum Jump: