meerk40t / svgelements

SVG Parsing for Elements, Paths, and other SVG Objects.
MIT License
143 stars 29 forks source link

Drawing sharp quadratic bezier curves #194

Closed ghost closed 2 years ago

ghost commented 2 years ago

This is not really an issue, but more a call for help! I am trying to find out how to draw a quadratic bezier curve with sharp ends, something like the following (drawn with Inkscape):

slur

My questions are basically whether svgelements is suitable for making complex quadratic bezier curves, and if so I would be very grateful if some one could give me a code hint as to how to do it. And also how could I modify the resulting path to achieve the sharp ends of the curve.

Many thanks!

tatarize commented 2 years ago

svgelements isn't very commonly used for making files, mostly parsing geometry from svg. This is mostly a rendering thing, which svgelements doesn't do at all (make pixels out of shapes). What the sharp at the end there would be a stroke-linecap. But there is absolutely not one for super-stabby stroke-linecap.

What you need to do is make that a filled shape. You're not drawing a quadratic bezier curve with sharp ends. You're drawing two quadratic bezier curves with a small offset in a filled closed shape. There's no way to draw that thing otherwise. In fact your shapes are pretty obviously going to share a start and end point and you are merely going to set the control point to being slightly different than the other. The difference in that shape will be filled.

Unless the stuff you're using to render things is something weird or you're actually wanting to do the rendering to draw that in an image directly or something (Pillow might have stuff for doing that).

ghost commented 2 years ago

Thank you for your answer! Could you maybe give a code snippet for the two curves with offset? That would help alot for understanding!

tatarize commented 2 years ago

It depends a bit on your application. Are you running this just in chrome or whatever? A single off somewhat static svg? Or do you have a needed programming language rendering engine and want generic code that will generally work in most cases.

Mostly in svg:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meerk40t="https://github.com/meerk40t/meerk40t/wiki/Namespace" width="110.0mm" height="110.0mm" viewBox="0 0 416 416">
    <path d="M0,200Q200,150 400,200Q200,160 0,200Z" id="sharp" stroke="none" fill="black"/>
</svg>

sharp2

The method's fairly obvious. You pick a start point and end point and a control point. And you'll probably want the control point to be like 10 units or so away from the other control point. So you draw the same curve twice and but tweak one of the control points. Close the path and fill with black.

ghost commented 2 years ago

WOW!!! This looks so obvious now! 👍 Yes, the application is output of a music notation application, so a static svg file (rendered to pdf). Thank you so much! Your code example saved my day!