Message Boards Message Boards

1
|
3997 Views
|
1 Reply
|
2 Total Likes
View groups...
Share
Share this post:

Make a part of an ellipse as a BSplineCurve?

Posted 6 years ago

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 = 
    Accumulate[
     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];
   Return[ctrlpts];
   ];

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 BY: Juerg Baertsch
Posted 6 years 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} + 
       Sin[t]*{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]];
   BSplineCurve[pts]
   ];

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.

POSTED BY: Juerg Baertsch
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract