Message Boards Message Boards


Make a part of an ellipse as a BSplineCurve?

Posted 5 months ago
1 Reply
2 Total Likes

Hello everybody

I didnt find a possibilty to search the forum (where is it?), so I'm sorry, if this isn't a new question.

I want to make a part of an ellipse as a BSplineCurve, so that I can use it with Arrow and FilledCurve. In the help of Mathematica, I found an example where they calculate the control-points for BSplineCurve to interpolate some random points:

interpolate[pts_] := Module[
   {dist, param, deg, knots, m, ctrlpts, i},
   dist = 
     Table[EuclideanDistance[pts[[i]], pts[[i + 1]]], {i, 
       Length[pts] - 1}]];
   param = N[Prepend[dist/Last[dist], 0]];
   deg = 3;
   knots = 
    Join[{0, 0, 0}, Range[0, 1, 1/(Length[pts] - deg)], {1, 1, 1}];
   m = Table[
     BSplineBasis[{deg, knots}, j - 1, param[[i]]], {i, 
      Length[pts]}, {j, Length[pts]}];
   ctrlpts = LinearSolve[m, pts];

Now I define a parametric function of circle and some points on it, and this works pretty well: (Yellow=ParametricPlot, Blue=BSplineCurve[points], Red=BSplineCurve[interpolate[points]])

a = {1, 0}; b = {0, 1};
el = (Cos[#]*a + Sin[#]*b) &;
t1 = \[Pi]/6; t2 = 11 \[Pi]/6; n = 10;
pts = Table[el[t], {t, t1, t2, (t2 - t1)/n}];

enter image description here

But if I do the same for an ellipse, it's not good anymore.

a = {0.8, 0.1}; b = {0.2, 0.6};
el = (Cos[#]*a + Sin[#]*b) &;
t1 = \[Pi]/6; t2 = 11 \[Pi]/6; n = 10;
pts = Table[el[t], {t, t1, t2, (t2 - t1)/n}];

enter image description here

Is there a simple way, to make this better? If I make a BSplineCurve without interpolation, but with much more points, it looks ok, but I'm not really happy with this. Then I saw, there is an old Package "Spline" with a possibilty to interpolate. But its marked as an old package and the result could be better.

Thx for any help & kind regards. JotaBeta

Posted 5 months ago

I have found a solution for me that works fine. I calculate the point first for a cricle, interpolate them wit the function of the first post, then I transform them to the ellipse and mak the BSplineCurve:

ellipse[o_, a_, b_, \[Alpha]1_, \[Alpha]2_, n_] := Module[
   {m, o1, a1, b1, pts},
   m = TransformationMatrix[
     FindGeometricTransform[{{0, 0}, {1, 0}, {0, 1}}, {o, o + a, 
        o + b}][[2]]];
   pts = interpolate[
     Table[Cos[t]*{1, 0} + 
         1}, {t, \[Alpha]1, \[Alpha]2, (\[Alpha]2 - \[Alpha]1)/n}]];
   pts = Append[Transpose[pts], Table[1, Length[pts]]];
   pts = Transpose[Inverse[m].pts][[All, 1 ;; -2]];

The result looks perfect with only few points:

enter image description here

But this works only for ellipses. For now I'm happy with this workaround. But If somebody has a solution to convert any parametric functions in Splines, I'm still very interested in this.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract