Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong BSpline representation after ToBeziers #244

Closed
artemishenkov opened this issue May 28, 2024 · 3 comments
Closed

Wrong BSpline representation after ToBeziers #244

artemishenkov opened this issue May 28, 2024 · 3 comments

Comments

@artemishenkov
Copy link

Hi, I am using Tinyspline library(C#) to break down the BSpline(from dxf image) to beziers and put them into svg(
image
) format. When I am trying to apply ToBeziers method on one particular spline which is supposed to be a circle Tinyspline breaks down it in a different shape.
My spline:
ControlPoints:
998.24, 702.13
997.58, 693.92
1005.01, 697.45
1012.44, 700.97
1005.67, 705.65
998.9, 710.33
998.24, 702.13
Knots:
0
0
0
2.0943951023932
2.0943951023932
4.188790204786389
4.188790204786389
6.283185307179588
6.283185307179588
6.283185307179588
Degree: 2
Dimension: 2
My code(C#):
BSpline spline = new((uint)ControlPoints.Count, 2, (uint)Degree) { ControlPoints = points, Knots = Knots };

        BSpline beziers = spline.ToBeziers();

        var offset = (int)(spline.Order * spline.Dimension);
        var controls = beziers.ControlPoints;
        var length = controls.Count / offset;

        if (spline.Order == 4)
            for (int n = 0; n < length; n++)
                Beziers.Add(new GCubicBezier()
                {
                    Start = new(controls[n * offset], controls[n * offset + 1]),
                    Second = new(controls[n * offset + 2], controls[n * offset + 3]),
                    Third = new(controls[n * offset + 4], controls[n * offset + 5]),
                    End = new(controls[n * offset + 6], controls[n * offset + 7])
                });
        else if (spline.Order == 3)
            for (int n = 0; n < length; n++)
                Beziers.Add(new GQuadraticBezier
                {
                    Start = new(controls[n * offset], controls[n * offset + 1]),
                    Middle = new(controls[n * offset + 2], controls[n * offset + 3]),
                    End = new(controls[n * offset + 4], controls[n * offset + 5])
                });
        else if (spline.Order == 2)
            for (int n = 0; n < length; n++)
                Beziers.Add(new GSporadicBezier
                {
                    Start = new(controls[n * offset], controls[n * offset + 1]),
                    End = new(controls[n * offset + 2], controls[n * offset + 3])
                });

I would appreciate any help. Thank you.

@msteinbeck
Copy link
Owner

It looks like you are mixing NURBS and B-Splines. I will take a closer look.

@msteinbeck
Copy link
Owner

In your screenshot you can see that there is a "Weight" component associated to your data points. The weight is probably not 1 for all control points (otherwise your B-Spline cannot form a circle; see: https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline#Example:_a_circle). You have to encode your control points as homogeneous coordinates, pass them to TinySpline, and decode them back to the presentation supported by your rendering code.

@artemishenkov
Copy link
Author

Thank you for your response @msteinbeck. You are totally right the Weights are different. I will try to follow your response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants