Page 1 of 1

DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-06T13:21:19-07:00
by Danack
Can anyone point me to any example of how this is used in SVG?

I don't mind what language or platform - I'm just failing to understand how this part of the SVG spec is meant to be used. For example the code below generates the image

Image

which in no way is smooth or even a curve.

Code: Select all

$image = new Imagick();
$image->newImage(800, 500, 'none', 'png');

$bezier1 = new ImagickDraw();
$bezier1->setFillColor('#B42AAF');
$bezier1->setStrokeColor('black');
$bezier1->setStrokeWidth(1);

$bezier1->pathStart();
$bezier1->pathMoveToAbsolute(50, 200);

// This specifies a bezier curve with the current position as the start
// point, two control points, and an end point.
$bezier1->pathCurveToAbsolute(
    50, 140,
    250, 140,
    250, 200
);


// This specifies a bezier curve with the current position as the start
// point, the first control point is a 'mirrored' from the previous bezier
// curve, and the value here specify the second control point and the end point.
$bezier1->pathCurveToSmoothAbsolute(
    450, 260,
    450, 200
);


//apparently draws a straight line
$bezier1->pathCurveToQuadraticBezierSmoothAbsolute(
    650,
    230
);

$bezier1->pathFinish();
$image->drawImage($bezier1);

header('Content-Type: image/png');
echo $image;


Re: DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-06T14:29:17-07:00
by snibgo
I don't understand what you are asking.

The same curve can be drawn directly in IM (Windows BAT syntax):

Code: Select all

convert ^
  -size 800x500 xc: ^
  -fill #B42AAF ^
  -stroke Black ^
  -draw "path 'M50,200 C50,140,250,140,250,200 S450,260,450,200 T650,230 z'" ^
  c.png
For the meanings of M, C, etc see http://www.w3.org/TR/SVG/paths.html

It could be written as a SVG file.

Re: DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-06T16:44:56-07:00
by Danack
"I don't understand what you are asking."

Every description of the function describes it as drawing a 'smooth bezier curve'. It only seems to draw a straight line. The exact question I was asking is 'how do you use it to draw a curve' ?

I think possibly I've possibly found what I was misunderstanding before from http://www.w3.org/TR/SVG/paths.html#Pat ... erCommands

"Draws a quadratic Bézier curve from the current point to (x,y). The control point is assumed to be the reflection of the control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not a Q, q, T or t, assume the control point is coincident with the current point.)"

So basically it's used to draw quadratic beziers, and you can't use it to smoothly continue a cubic bezier? So it's to be expected that in the command `draw "path 'M50,200 C50,140,250,140,250,200 S450,260,450,200 T650,230 z'" ` because the S command is a cubic bezier, the T command doesn't join it smoothly.

Is that correct?

Re: DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-06T17:03:09-07:00
by snibgo
Danack wrote:So basically it's used to draw quadratic beziers, and you can't use it to smoothly continue a cubic bezier?
Correct. "T" or will draw a straight line unless the previous was T or Q (or the lower-case versions).

To smoothly continue a cubic into a quadratic, you need "Q" with a specified control point, eg:

Code: Select all

convert ^
  -size 800x500 xc: ^
  -fill #B42AAF ^
  -stroke Black ^
  -draw "path 'M50,200 C50,140,250,140,250,200 S450,260,450,200 Q450,140,650,230 z'" ^
  c2.png

Re: DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-06T17:55:02-07:00
by fmw42
Bezier splines are approximating splines. They do not pass through the control points. You want an interpolating spline that goes through each control point. See my (unix) script, spline at http://www.fmwconcepts.com/imagemagick/spline/index.php

Re: DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-07T07:18:28-07:00
by Danack
I'm still a little confused by some behaviour - consider the two commands:

convert -size 800x500 xc: -fill "#B42AAF" -stroke Black -draw "path 'M50,200 T200,250 z'" curveT.png
convert -size 800x500 xc: -fill "#B42AAF" -stroke Black -draw "path 'M50,200 Q50,200,200,250 z'" curveQ.png

For the first one that uses the T command the control point should be calculated with (If there is no previous command or if the previous command was not a Q, q, T or t, assume the control point is coincident with the current point.)", so:

* The starting point is 50,200.
* The control point is 50,200 due to lack of previous quadratic curve.
* The end point is 200,250.

Which is what the second command is doing. But the images produced are different. So have I misunderstood something or what is the reason for the images being different?

Similarly, I would expect these two commands to produce the same image as each other, but again they are quite different.

convert -size 800x500 xc: -fill "#B42AAF" -stroke Black -draw "path 'M50,200 T200,250 T400,250 z'" curve2T.png
convert -size 800x500 xc: -fill "#B42AAF" -stroke Black -draw "path 'M50,200 Q50,200,200,250 T400,250 z'" curveQT.png


CurveQ
Image

CurveT
Image

I'm also confused by the lack of fill color in the 'area' defined in curveT

Re: DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-07T08:14:34-07:00
by snibgo
The result of curveT looks wrong. I would expect the output to have two points, not three. Perhaps IM has a bug.

Curve2T also looks wrong.

With an SVG file and Inkscape, we get the identical images as you expect.

This is the kind of bug that isn't easily noticed.

Re: DrawPathCurveToQuadraticBezierSmooth example

Posted: 2014-12-07T09:14:33-07:00
by Danack
In that case, I have opened an issue in the bug forum - viewtopic.php?f=3&t=26655