Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to draw Quadric Bezier line in Gdi+

288 views
Skip to first unread message

pango

unread,
Jun 14, 2004, 9:24:01 AM6/14/04
to
We know we can use the Graphics::DrawBezier() to draw Bezier line,but it is a Cubic Bezier line(it has 4 points),so how to draw Quadric Bezier line(it has 3 points) in Gdi+?

Feng Yuan [MSFT]

unread,
Jun 15, 2004, 1:21:35 AM6/15/04
to
Quadric curve can be easily converted into cubic curves. But I do not
remember the formula now.

You should be able to find some code here
http://safariexamples.informit.com/0130869856/ (Check for TrueType font
decoding code).

--
Feng Yuan (https://blogs.msdn.com/fyuan, www.fengyuan.com)

This posting is provided "AS IS" with no warranties, and confers no rights.

"pango" <pa...@discussions.microsoft.com> wrote in message
news:684C5041-4E95-4ECE...@microsoft.com...

Boris Novgorodov

unread,
Jun 15, 2004, 6:28:40 AM6/15/04
to
> how to draw Quadric Bezier line

New control points to create cubic Bezier from quadratic (2nd degree) one :

P'i = ki*P(i&#8722;1) + (1 &#8722; ki)P(i)

where ki = i/3 (i/n for degree elevation from (n-1) to n)

Mike D Sutton

unread,
Jun 15, 2004, 8:46:03 AM6/15/04
to
> We know we can use the Graphics::DrawBezier() to draw Bezier line,but it is a Cubic Bezier line
> (it has 4 points),so how to draw Quadric Bezier line(it has 3 points) in Gdi+?

This works pretty well here at approximating a single QSpline curve with a cubic Bezier:

***
BezPts[0] = Pts[0]; // End points are the same
BezPts[3] = Pts[2]; // Project curve handles
BezPts[1].X = (Pts[0].X + Pts[1].X + Pts[1].X) / 3;
BezPts[1].Y = (Pts[0].Y + Pts[1].Y + Pts[1].Y) / 3;
BezPts[2].X = (Pts[2].X + Pts[1].X + Pts[1].X) / 3;
BezPts[2].Y = (Pts[2].Y + Pts[1].Y + Pts[1].Y) / 3;
***

Where Pts[] are the original curve points, and BezPts[] are the Bezier points.
If you have multiple connected QSpline segments then you'll need something like this instead:

*** Warning; air code..
int NumCurve = PointCount - 2;
int PtIdx = 0;

BezPts[0] = Pts[0].X;

for (int LoopCurve = 0; LoopCurve < NumCurve, LoopCurve++) {
if (LoopCurve = (NumCurve - 1)) {
BezPts[PtIdx + 3] = Pts[NumCurve + 1];
} else {
BezPts[PtIdx + 3] = (Pts[LoopCurve + 1].X + Pts[LoopCurve + 2].X) / 2;
BezPts[PtIdx + 3] = (Pts[LoopCurve + 1].Y + Pts[LoopCurve + 2].Y) / 2;
}

BezPts[PtIdx + 1].X = (BezPts[PtIdx].X +
Pts[LoopCurve + 1].X + Pts[LoopCurve + 1].X) / 3;
BezPts[PtIdx + 1].Y = (BezPts[PtIdx].Y +
Pts[LoopCurve + 1].Y + Pts[LoopCurve + 1].Y) / 3;
BezPts[PtIdx + 2].X = (BezPts[PtIdx + 3].X +
Pts[LoopCurve + 1].X + Pts[LoopCurve + 1].X) / 3;
BezPts[PtIdx + 2].Y = (BezPts[PtIdx + 3].Y +
Pts[LoopCurve + 1].Y + Pts[LoopCurve + 1].Y) / 3;
PtIdx += 3;
}
***

Finally, if you have a closed QSpline then you'll need something like this:

*** Warning; air code..
int NumCurve = PointCount;
int PtIdx = 0;

BezPts[0].X = (Pts[NumCurve - 1].X + Pts[0].X) / 2;
BezPts[0].Y = (Pts[NumCurve - 1].Y + Pts[0].Y) / 2;

for (int LoopCurve = 0; LoopCurve < NumCurve; LoopCurve++) {
BezPts[PtIdx + 3].X = (Pts[LoopCurve].X +
Pts[(LoopCurve + 1) % NumCurve].X) / 2;
BezPts[PtIdx + 3].Y = (Pts[LoopCurve].Y +
Pts[(LoopCurve + 1) % NumCurve].Y) / 2;
BezPts[PtIdx + 1].X = (BezPts[PtIdx].X +
Pts[LoopCurve].X + Pts[LoopCurve].X) / 3;
BezPts[PtIdx + 1].Y = (BezPts[PtIdx].Y +
Pts[LoopCurve].Y + Pts[LoopCurve].Y) / 3;
BezPts[PtIdx + 2].X = (BezPts[PtIdx + 3].X +
Pts[LoopCurve].X + Pts[LoopCurve].X) / 3;
BezPts[PtIdx + 2].Y = (BezPts[PtIdx + 3].Y +
Pts[LoopCurve].Y + Pts[LoopCurve].Y) / 3;
PtIdx += 3;
}
***

Where "PointCount" in the last two example is the number of points in your source QSpline.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://www.mvps.org/EDais/


0 new messages