4
$\begingroup$

I want to draw the outline of a circle (it's actually the glyph period from Cascadia Code font):

points = {
  {{600.,-20.},{518.,-20.},{452.,46.},{452.,128.}},
  {{452.,128.},{452.,210.},{518.,276.},{600.,276.}},
  {{600.,276.},{682.,276.},{748.,210.},{748.,128.}},
  {{748.,128.},{748.,46.},{682.,-20.},{600.,-20.}}
};
Graphics /@ {
  {
    PointSize[0.02], Point @ Flatten[points, 1],
    BezierCurve /@ points,
    Opacity[0.2, Blue], FilledCurve[BezierCurve /@ points]
  },
  {
    PointSize[0.02], Point @ Flatten[points, 1],
    BSplineCurve /@ points,
    Opacity[0.2, Red], FilledCurve[BSplineCurve /@ points]
  }
} // GraphicsRow

enter image description here

  • Black "circle": drawn by BezierCurve or BSplineCurve
  • Blue region: FilledCurve @ BezierCurve
  • Red region: FilledCurve @ BSplineCurve

Why the curve and the filled region do no fit whether I use BezierCurve or BSplineCurve?

$\endgroup$
4
  • 1
    $\begingroup$ The BezierCurve corners make sense because it's actually a collection of splines glued together in a C0 continuous way. BSplineCurve looks smoother because they're joined in a C2 continuous way. There is unfortunately no way to make an exact circle with these splines - but you can get close - look at this answer stackoverflow.com/questions/1734745/… $\endgroup$
    – flinty
    Commented Jun 1, 2020 at 14:38
  • $\begingroup$ @flinty I know that the circle can't be represented exactly by Bezier curves. But my question is that why the filled region and the enclosed curve do not fit? $\endgroup$
    – stone-zeng
    Commented Jun 1, 2020 at 14:41
  • 5
    $\begingroup$ Did you read the docs for FilledCurve[]? Try omitting the first point of the second, third, and fourth set of control points before feeding to FilledCurve[]: Graphics[{PointSize[0.02], Point @ Flatten[points, 1], BezierCurve /@ points, Opacity[0.2, Blue], FilledCurve[BezierCurve /@ Join[{First[points]}, Drop[points, 1, 1]]]}] $\endgroup$ Commented Jun 1, 2020 at 15:07
  • $\begingroup$ @J.M. Oh really thank you for your comment! It works perfectly. $\endgroup$
    – stone-zeng
    Commented Jun 1, 2020 at 15:12

1 Answer 1

1
$\begingroup$

Filling in an answer from @J.M.'s comment:

Did you read the docs for FilledCurve[]? Try omitting the first point of the second, third, and fourth set of control points before feeding to FilledCurve[]: Graphics[{PointSize[0.02], Point @ Flatten[points, 1], BezierCurve /@ points, Opacity[0.2, Blue], FilledCurve[BezierCurve /@ Join[{First[points]}, Drop[points, 1, 1]]]}] – J. M. can't deal with it♦ Jun 1, 2020 at 15:07

points = {{{600., -20.}, {518., -20.}, {452., 46.}, {452., 128.}},
   {{452., 128.}, {452., 210.}, {518., 276.}, {600., 276.}},
   {{600., 276.}, {682., 276.}, {748., 210.}, {748., 128.}},
   {{748., 128.}, {748., 46.}, {682., -20.}, {600., -20.}}};
Graphics[{PointSize[0.02], Point@Flatten[points, 1], 
  BezierCurve /@ points, Opacity[0.2, Blue], 
  FilledCurve[
   BezierCurve /@ Join[{First[points]}, Drop[points, 1, 1]]]}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.