Display of Bezier Curves in C#
Display of Bezier Curves in C#
Hello,
I have got the following problem:
I use Inkscape to import a PDF that contains a vector graphic and export to normal svg. When I use Inkscape or Firefox to view the generated svg file everything is ok.
When I parse the svg using C# code and try to draw what I parsed on a C# Windows Form, some Bezier-Curves end up wrong: instead of a circle consisting of 4 Bezier-curves (that's how Inkscape decides to draw the circle) I get four Bezier-curves building the shape of a diamond rather than a circle.
The parsing code works - the numbers it turns out are the numbers in the XML.
I cannot find any transformations arround, that could change the coordinates of the Bezier points.
So why can Inkscape and Firefox turn that coordinates into a circle, while C# cannot?
There might be a general inconsistency (a different point of view) in the way C# draws Bezier-curves and how SVG software treats them?
Thanks in advance!
I have got the following problem:
I use Inkscape to import a PDF that contains a vector graphic and export to normal svg. When I use Inkscape or Firefox to view the generated svg file everything is ok.
When I parse the svg using C# code and try to draw what I parsed on a C# Windows Form, some Bezier-Curves end up wrong: instead of a circle consisting of 4 Bezier-curves (that's how Inkscape decides to draw the circle) I get four Bezier-curves building the shape of a diamond rather than a circle.
The parsing code works - the numbers it turns out are the numbers in the XML.
I cannot find any transformations arround, that could change the coordinates of the Bezier points.
So why can Inkscape and Firefox turn that coordinates into a circle, while C# cannot?
There might be a general inconsistency (a different point of view) in the way C# draws Bezier-curves and how SVG software treats them?
Thanks in advance!
Re: Display of Bezier Curves in C#
i've no idea why you're somehow using bezier curves for a circle when inkscape and plain svg support ellipse native element, a circle being a special case of an ellipse.
in any case sounds like you're not drawing (and setting appropriate values for strength and direction) for the bezier handles that should exist at the midpoint of each of your lines.
also...are you using some svg rendering library in c# ? or some other rendering library. none of these details or any code posted. pretty hard to guess what's the cause without any level of detail.
in any case sounds like you're not drawing (and setting appropriate values for strength and direction) for the bezier handles that should exist at the midpoint of each of your lines.
also...are you using some svg rendering library in c# ? or some other rendering library. none of these details or any code posted. pretty hard to guess what's the cause without any level of detail.
Re: Display of Bezier Curves in C#
chriswww wrote:i've no idea why you're somehow using bezier curves for a circle when inkscape and plain svg support ellipse native element
Maybe he (or the "generator") turns the basic objects into paths ?
pretty hard to guess what's the cause without any level of detail.
indeed
By looking at http://svg.codeplex.com/SourceControl/c ... 10#1540942 (src/paths) it looks rather straightforward.
Re: Display of Bezier Curves in C#
yeah. was questioning the statement about inkscape deciding to use beziers for circles. one could possibly redraw as a real circle by hand in inkscape and delete that part from the pdf import or otherwise try to fix why this happens in the first place. is the circle in the pdf really thin and thus too thin at certain points and converts to beziers?
still speculating
still speculating
Re: Display of Bezier Curves in C#
Hello,
meanwhile I found out, what is going wrong, thanks for the answers so far - next time I will post more details.
The reason, why I approximate a circle with four Beziers is, that inkscape does so, when I load my PDF and convert it to SVG. Editing by hand is no option, since I have a lot of PDFs. The parsing of the SVG/XML is done by a C# xmlReader.
The reason for the problems I encountered is the following (I'm writing this because somebody else might comit the same error as I did):
Given a Bezier-Path with relative coordinates:
<path
d="m 313.8,567.24 0,0 m 0,0 c 0,-3.9102 -3.1698,-7.08 -7.08,-7.08 -3.9102,0 -7.08,3.1698 -7.08,7.08 0,3.9102 3.1698,7.08 7.08,7.08 3.9102,0 7.08,-3.1698 7.08,-7.08"
style="fill:none;stroke:#000000;stroke-opacity:1;stroke-width:0.24;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none"
id="path22" />
the "moving point" philosophy does NOT mean, that one has to start with the first point (313.8, 567.24) and to add the relative coordinates given to obtain every other point. The way to do it here seems rather that you allways start from the first point of your Bezier curve:
First Bezier-Curve:
First point: (313.8, 567.24) +(0, 0) = (313.8, 567.24 )
Second point: (313.8, 567.24) + (0, -3.9102) = (313.8, 563.3298)
Third point: (313.8, 567.24) + (-3.1698,-7.08) = (310.6302, 560.16)
Fourth point: (313.8, 567.24) + (-7.08,-7.08) = (306.72, 560.16)
Second Bezier Curve:
(the fourth point of the previous curve is the first of the next)
First point: (306.72, 560.16)
Second point: (306.72, 560.16) + (-3.9102,0) = (302.8098, 560.16)
Third point: (306.72, 560.16) + (-7.08,3.1698) = (299.64, 563.3298)
Fourth point: (306.72, 560.16) + (-7.08,7.08) = (299.64, 567.24)
and so on...
Somehow I could not read this from the W3C specification or elsewhere, but it works (while everything else did not), so I assume this is the right way to do it.
Thank You everybody
meanwhile I found out, what is going wrong, thanks for the answers so far - next time I will post more details.
The reason, why I approximate a circle with four Beziers is, that inkscape does so, when I load my PDF and convert it to SVG. Editing by hand is no option, since I have a lot of PDFs. The parsing of the SVG/XML is done by a C# xmlReader.
The reason for the problems I encountered is the following (I'm writing this because somebody else might comit the same error as I did):
Given a Bezier-Path with relative coordinates:
<path
d="m 313.8,567.24 0,0 m 0,0 c 0,-3.9102 -3.1698,-7.08 -7.08,-7.08 -3.9102,0 -7.08,3.1698 -7.08,7.08 0,3.9102 3.1698,7.08 7.08,7.08 3.9102,0 7.08,-3.1698 7.08,-7.08"
style="fill:none;stroke:#000000;stroke-opacity:1;stroke-width:0.24;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none"
id="path22" />
the "moving point" philosophy does NOT mean, that one has to start with the first point (313.8, 567.24) and to add the relative coordinates given to obtain every other point. The way to do it here seems rather that you allways start from the first point of your Bezier curve:
First Bezier-Curve:
First point: (313.8, 567.24) +(0, 0) = (313.8, 567.24 )
Second point: (313.8, 567.24) + (0, -3.9102) = (313.8, 563.3298)
Third point: (313.8, 567.24) + (-3.1698,-7.08) = (310.6302, 560.16)
Fourth point: (313.8, 567.24) + (-7.08,-7.08) = (306.72, 560.16)
Second Bezier Curve:
(the fourth point of the previous curve is the first of the next)
First point: (306.72, 560.16)
Second point: (306.72, 560.16) + (-3.9102,0) = (302.8098, 560.16)
Third point: (306.72, 560.16) + (-7.08,3.1698) = (299.64, 563.3298)
Fourth point: (306.72, 560.16) + (-7.08,7.08) = (299.64, 567.24)
and so on...
Somehow I could not read this from the W3C specification or elsewhere, but it works (while everything else did not), so I assume this is the right way to do it.
Thank You everybody
Re: Display of Bezier Curves in C#
i made a circle as a pdf and imported it back into inkscape, and it became a four node closed path that exactly resembles a circle.
that's why i was mentioning to check some assumptions about inkscape deciding that a circle imported from pdf becomes four separate paths...it all depends on the quality of the circle(s). are you calling inskcape in batch with commands or is this what came out when doing a single file by hand?
regards to your svg path statement, I'm not sure how forgiving each interpreter is but afaik the letter commands aren't supposed to have a space after them before a number? e.g. m313.8,567.24 0,0 m0,0 c0,-3.9102
hope you get to where you're going with this. sounds like some fun transformations.
that's why i was mentioning to check some assumptions about inkscape deciding that a circle imported from pdf becomes four separate paths...it all depends on the quality of the circle(s). are you calling inskcape in batch with commands or is this what came out when doing a single file by hand?
regards to your svg path statement, I'm not sure how forgiving each interpreter is but afaik the letter commands aren't supposed to have a space after them before a number? e.g. m313.8,567.24 0,0 m0,0 c0,-3.9102
hope you get to where you're going with this. sounds like some fun transformations.
Re: Display of Bezier Curves in C#
PsBoSC wrote:
the "moving point" philosophy does NOT mean, that one has to start with the first point (313.8, 567.24) and to add the relative coordinates given to obtain every other point. The way to do it here seems rather that you allways start from the first point of your Bezier curve:
Somehow I could not read this from the W3C specification
"moving point" (coordinates of the nth element is relative to nth-1) applies to polyXXX.
It's the same for bezier except that the "element" is composed of (2 control points + 1 real point).
There's no strong relation between control point 1 & 2, so it will make little sense to make cp2 coordinates relative to cp1.
So all 3 points ( = 6 coordinates) are relative to the preceeding reference element.
http://www.w3.org/TR/SVG11/paths.html#P ... erCommands
Draws a cubic Bézier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve. C (uppercase) indicates that absolute coordinates will follow; c (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be specified to draw a polybézier. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybézier.
Re: Display of Bezier Curves in C#
@vince:
You are probably right, when you say that there is no "strong relationship" between the two control points. Neither are there between the first point and the control points - you can choose them as you want/ have to. I don't want to argue: the only thing I would have liked to see somewhere is an example of how things are done, without having to wonder about "strong" relationships between points and possibly "not so strong" realtionships. A simple example would have explained everything and saved much time and effort for me - the most difficult thing is to get rid of assumptions, whose validity you never doubt, like I did, when I believed, that relative coordinates DO mean: add them to the previous point and you will get the next one. But anyway: your post explanes the rationale behind the behavior.
@ chriswww:
I called Inkscape with a single pdf document by hand, to test my algorithm to parse the XML and display the graphics in a windows form. The next thing to undertake will be calling Inkscape from C# and when this works well, batch will be the next thereafter.
The path I posted was pasted from notepad++, so I assume, that is what Inkscape produces?
You wrote about some assumptions Inkscape makes, to decide, if to represent a circle as four beziers - do you know something about these asumptions? For the time being, I'm satisfied with my output, but I allready feel, that an internal voice starts to nag about this...
@
You are probably right, when you say that there is no "strong relationship" between the two control points. Neither are there between the first point and the control points - you can choose them as you want/ have to. I don't want to argue: the only thing I would have liked to see somewhere is an example of how things are done, without having to wonder about "strong" relationships between points and possibly "not so strong" realtionships. A simple example would have explained everything and saved much time and effort for me - the most difficult thing is to get rid of assumptions, whose validity you never doubt, like I did, when I believed, that relative coordinates DO mean: add them to the previous point and you will get the next one. But anyway: your post explanes the rationale behind the behavior.
@ chriswww:
I called Inkscape with a single pdf document by hand, to test my algorithm to parse the XML and display the graphics in a windows form. The next thing to undertake will be calling Inkscape from C# and when this works well, batch will be the next thereafter.
The path I posted was pasted from notepad++, so I assume, that is what Inkscape produces?
You wrote about some assumptions Inkscape makes, to decide, if to represent a circle as four beziers - do you know something about these asumptions? For the time being, I'm satisfied with my output, but I allready feel, that an internal voice starts to nag about this...
@
Re: Display of Bezier Curves in C#
You are probably right, when you say that there is no "strong relationship" between the two control points.
Neither are there between the first point and the control points - you can choose them as you want/ have to
For me there's a strong relationship between current point and control point 1 (If you try to draw it by hand you'll understand)
but I agree there's none between current point and control point2
So the spec could possibly have been better (I'd have make cp2 relative to end point)
A simple example would have explained everything
That's what I think everywhen I'd have to look at MSDN
Yeah docs always lack the tiny exemple you're after
To get it right, you got to mix
8.3.1
For the relative versions of the commands, all coordinate values are relative to the current point at the start of the command.
and 8.3.6
<= you should not consider the n values after a 'c' like a collection of n points but like a collection of n/3 (3uple of coordinates)(x1 y1 x2 y2 x y)+
with all values in the 3uple being relative to current point. When "exiting" a 3uple the doc says the current point is now the last point of the 3uple.
Re: Display of Bezier Curves in C#
Just a quick note, it's not possible to describe an exact circle with Bézier curves, whatever their degree (you need rational Béziers for that). Inkscape only uses cubic Béziers (when your file contains quadratic Béziers, they get degree-elevated to cubic ones, such that there are two control points and two handles).
When converting a circle to a path, Inkscape approximates the circle with 4 cubic Béziers, such that the approximation is more or less optimal .
When converting a circle to a path, Inkscape approximates the circle with 4 cubic Béziers, such that the approximation is more or less optimal .
Re: Display of Bezier Curves in C#
@vince:
Your remark got me thinking:
If you write a path like:
m2,0 6,8 4,5 ...
this looks like a "chain" of coordinates, when added one to the previous give you a "chain" of points: that picture seems to fit to the idea of "the moving point" and leads to the missunderstanding I made when I tried it with my polycubicbeziers. In reality the path is:
m2,0 L6,8 L4,5 ...
so your quote 8.3.1 from the spec applies, because the letter "L" starts a new command, having a new current point to relate to. Finally I can see the consistency within the specification.
@ Ailurus:
the specification of svg comprises quadratic beziers, but as you mentioned it: I never saw one in the xml/svg files inkscape produces. As far as I've found out, the four bezier-curves inkscape uses to draw a circle, are determined by the start and endpoint and a point 45 degree from the starting point. Because of symmetry there is just one parameter left to be determined, when you have start and endpoint, e.g. the distance of the first controllpoint from the starting point. This will give you the first controll point and, like i said, the second one by symmetry. To calculate this unknown parameter inkscape seems to use the additional assumption that the bezier should touch the circle at the point 45 degrees of the startingpoint.
(in my quest for why my beziers are so wry and ugly, I started to calculate the error-integral measuring the deviation of the cubic bezier from the circle and tried to determine the optimal parameter value by minimizing this integral; but I became suspicious if this is the way inkscape would do this thing and I grew more suspicious because the error- integral might depend on the parametrization of the circle (at least I think so): at that point I posed my question in this forum...) - But we're a little bit of topic now...
Your remark got me thinking:
If you write a path like:
m2,0 6,8 4,5 ...
this looks like a "chain" of coordinates, when added one to the previous give you a "chain" of points: that picture seems to fit to the idea of "the moving point" and leads to the missunderstanding I made when I tried it with my polycubicbeziers. In reality the path is:
m2,0 L6,8 L4,5 ...
so your quote 8.3.1 from the spec applies, because the letter "L" starts a new command, having a new current point to relate to. Finally I can see the consistency within the specification.
@ Ailurus:
the specification of svg comprises quadratic beziers, but as you mentioned it: I never saw one in the xml/svg files inkscape produces. As far as I've found out, the four bezier-curves inkscape uses to draw a circle, are determined by the start and endpoint and a point 45 degree from the starting point. Because of symmetry there is just one parameter left to be determined, when you have start and endpoint, e.g. the distance of the first controllpoint from the starting point. This will give you the first controll point and, like i said, the second one by symmetry. To calculate this unknown parameter inkscape seems to use the additional assumption that the bezier should touch the circle at the point 45 degrees of the startingpoint.
(in my quest for why my beziers are so wry and ugly, I started to calculate the error-integral measuring the deviation of the cubic bezier from the circle and tried to determine the optimal parameter value by minimizing this integral; but I became suspicious if this is the way inkscape would do this thing and I grew more suspicious because the error- integral might depend on the parametrization of the circle (at least I think so): at that point I posed my question in this forum...) - But we're a little bit of topic now...
Re: Display of Bezier Curves in C#
PsBoSC wrote:the specification of svg comprises quadratic beziers, but as you mentioned it: I never saw one in the xml/svg files inkscape produces.
And you probably never will . That's just because cubic Béziers are the easiest to handle (pun not intended), most intuitive. In fact there are 4 control points, but since the first and last ones are interpolated, inkscape interprets only those 2 points as control points, and the other two as handles.
A quadratic Bézier would only have one handle, which might be a little strange.
Nice to experiment: create an SVG file from scratch (in notepad or whatever), with a quadratic Bézier curve. Then open it in Inkscape, save it again et voila: a cubic Bézier
PsBoSC wrote:As far as I've found out, the four bezier-curves inkscape uses to draw a circle, are determined by the start and endpoint and a point 45 degree from the starting point.
I'm not entirely sure how Inkscape handles this, but a common solution is described on this page. I actually did the same thing as you, calculating the error between the perfect circle and Bézier representation. Sorry for another relatively off-topic post, but this subject is just too interesting not to discuss it a little!
Re: Display of Bezier Curves in C#
Yes, the side you linked to, derives the coordinates for the controll-points by assuming the bezier should touch half-ways. When I took my inkscape generated numbers and checked the coordinates I found, that the controll points' coordinates use precisely this "kappa". That's why I concluded that inkscape probably does it this way - the result is good enough and the only thing to remember is the value for "kappa".
To use cubic beziers because it seems intuitive that the tangents at start and endpoint are given by the controll-points sounds right - though I don't see that this idea leads you anywhere when you start thinking about lower or higher order beziers, I mean: the idea is not enough to define bezier curves (if they hadn't allready been defined by Monsieur Bezier).
It would be interesting to know by which geometrical ideas, he was lead to his discovery - but on the other side: he's French and taking into account the abhorrence of intuitive geometric ideas French mathematics a la Bourbaki usually cultivates, he might have started with Bernstein Polynomials and and algebraic fiddling until something came out. On the other hand side: the animations shown on wikipedia give a hint to a geometric interpretation - to beautifull to be the result of algebraic fiddling only...I'm talking about the idea of a point travelling on a line while the line is travelling (at the same speed?) on two other lines, defined by... 3 points for quadratic, 2 lines (themselves moving) for cubic, ..., I guess that might be the idea behind it all (this is so "cute" it could be ancient Greek...)
But that should be discussed at leasure in a mathematics forum, I just couldn't contain myself..., special thanks to Ailurus.
To use cubic beziers because it seems intuitive that the tangents at start and endpoint are given by the controll-points sounds right - though I don't see that this idea leads you anywhere when you start thinking about lower or higher order beziers, I mean: the idea is not enough to define bezier curves (if they hadn't allready been defined by Monsieur Bezier).
It would be interesting to know by which geometrical ideas, he was lead to his discovery - but on the other side: he's French and taking into account the abhorrence of intuitive geometric ideas French mathematics a la Bourbaki usually cultivates, he might have started with Bernstein Polynomials and and algebraic fiddling until something came out. On the other hand side: the animations shown on wikipedia give a hint to a geometric interpretation - to beautifull to be the result of algebraic fiddling only...I'm talking about the idea of a point travelling on a line while the line is travelling (at the same speed?) on two other lines, defined by... 3 points for quadratic, 2 lines (themselves moving) for cubic, ..., I guess that might be the idea behind it all (this is so "cute" it could be ancient Greek...)
But that should be discussed at leasure in a mathematics forum, I just couldn't contain myself..., special thanks to Ailurus.
Re: Display of Bezier Curves in C#
Hah, it seems that there is a code to specify off-topic content (which makes our conversation now completely acceptable ). But seriously, perhaps a "Technical Talk" subforum wouldn't be such a bad idea?
Off topic:
Just a little more about Béziers: I've done a few projects regarding CAGD, and I'm about to start with my MSc thesis, so by now I'm pretty comfortable with the background of curves and surfaces. The best way to explain Bézier curves, in my opinion, is the de Casteljau algorithm (also called "scaffolding construction"). Paul de Casteljau discovered Bézier curves actually before Bézier did, but he wasn't allowed to publish his findings (he worked at Citroën). However, Bézier was allowed to publish it (worked at Renault), hence it bears his name. But de Casteljau's name comes back it that algorithm I named. What it basically does, is taking convex combinations of points ("repeated linear interpolation"). Indeed, those animations on Wikipedia are quite intuitive. If you're interested, there is a short report on rational Béziers on my site, the included references (on CAGD and Blossoming) might be helpful.Re: Display of Bezier Curves in C#
"Technical Talk"? Would Inkscape Ideas work? Or maybe Programming?
Basics - Help menu > Tutorials
Manual - Inkscape: Guide to a Vector Drawing Program
Inkscape Community - Inkscape FAQ - Gallery
Inkscape for Cutting Design
Manual - Inkscape: Guide to a Vector Drawing Program
Inkscape Community - Inkscape FAQ - Gallery
Inkscape for Cutting Design
Re: Display of Bezier Curves in C#
it still doesn't explain why renault was such an ugly car. oh wait, maybe it does.
i'm still at a loss to understand why the original pdf circles must become beziers in C# no matter what. i think circles have a lot more going for them than beziers..like the ratio between diameter and perimeter and the mestery about squaring a circle etc. polynomials have no relationship to each other, other than a vaguely similar function. i would love to see a car driving on bezier shaped wheels.
i'm still at a loss to understand why the original pdf circles must become beziers in C# no matter what. i think circles have a lot more going for them than beziers..like the ratio between diameter and perimeter and the mestery about squaring a circle etc. polynomials have no relationship to each other, other than a vaguely similar function. i would love to see a car driving on bezier shaped wheels.
Re: Display of Bezier Curves in C#
chriswww wrote:i'm still at a loss to understand why the original pdf circles must become beziers in C# no matter what.
For what I understand, this is not a C# issue (you could use AddEllipse).
It looks like the svg coming out of inkscape contains the Bezier, so the error occured while inkscape imported the pdf
(that's how Inkscape decides to draw the circle)
Or the original pdf already contains Bezier and not real circle.
Which seems to be the case from you own experience
i made a circle as a pdf and imported it back into inkscape, and it became a four node closed path that exactly resembles a circle.
Re: Display of Bezier Curves in C#
i thought the PO ended up with four separate bezier paths, one for each quadrant.
Re: Display of Bezier Curves in C#
Hi Andy.
Copied from here ?
Bezier-Curves-Made-Simple
bezier-curves-part-1-linear-algebra-series
bezier-curves-a-tutorial
Quadratic
RGDS
Ragnar
Copied from here ?
Bezier-Curves-Made-Simple
bezier-curves-part-1-linear-algebra-series
bezier-curves-a-tutorial
Quadratic
RGDS
Ragnar
Good Luck!
( ͡° ͜ʖ ͡°)
RGDS
Ragnar
( ͡° ͜ʖ ͡°)
RGDS
Ragnar
Re: Display of Bezier Curves in C#
andyadams wrote:.
ragstian wrote:Hi Andy.
Copied from here ?
Bezier-Curves-Made-Simple
bezier-curves-part-1-linear-algebra-series
bezier-curves-a-tutorial
Quadratic
RGDS
Ragnar
Off topic:
By the banning all posts disappear from a user (sadly at times), so when replying to a spammer I suggest to quote some part of their message.