Giter Site home page Giter Site logo

msteinbeck / tinyspline Goto Github PK

View Code? Open in Web Editor NEW
1.2K 64.0 202.0 4.42 MB

ANSI C library for NURBS, B-Splines, and Bézier curves with interfaces for C++, C#, D, Go, Java, Javascript, Lua, Octave, PHP, Python, R, and Ruby.

License: MIT License

CMake 14.08% C 49.94% C++ 9.48% Shell 2.99% SWIG 3.97% Makefile 0.04% Dockerfile 1.59% Python 0.81% Lua 14.74% Java 0.72% C# 0.77% Go 0.37% Ruby 0.49%
nurbs b-splines bezier-curves splines

tinyspline's Introduction

TinySpline

CI Security

TinySpline is a small, yet powerful library for interpolating, transforming, and querying arbitrary NURBS, B-Splines, and Bézier curves. The core of the library is written in ANSI C (C89) with a C++ wrapper for an object-oriented programming model. Based on the C++ wrapper, auto-generated bindings for C#, D, Go, Java, Javascript, Lua, Octave, PHP, Python, R, and Ruby are provided.

Table of Contents

License

MIT License - see the LICENSE file in the source distribution.

Features

  • Object-oriented programming model
  • B-Splines of any degree and dimensionality
  • Spline interpolation
    • Cubic natural
    • Centripetal Catmull–Rom
  • Evaluation
    • Knots
    • Sampling (multiple knots at once)
    • Equidistant points
    • Components (find y for given x)
  • Reparametrization by arc length
    • Mapping length <--> knot
  • Knot insertion (refinement)
  • Sub-spline extraction
  • Bézier curve decomposition
    • (also known as subdivision)
  • Derivative
  • Degree elevation
  • Computation of rotation minimizing frames
  • Morphing
  • Serialization (JSON)
  • Vector math

Installation

Pre-built Binaries

Releases can be downloaded from the releases page. In addition, the following package manager are supported:

Conan (C/C++):
https://conan.io/center/tinyspline

NuGet (C#):

<PackageReference Include="tinyspline" Version="0.6.0.1" />

Go:

go get github.com/tinyspline/[email protected]

Luarocks (Lua):

luarocks install --server=https://tinyspline.github.io/lua tinyspline

Maven (Java):

<dependency>
   <groupId>org.tinyspline</groupId>
   <artifactId>tinyspline</artifactId>
   <version>0.6.0-1</version>
</dependency>

PyPI (Python):

python -m pip install tinyspline

RubyGems (Ruby):

gem install tinyspline

Compiling From Source

See BUILD.md.

Getting Started

A variety of examples (tests) can be found in the test subdirectory.

The following listing shows a Python example:

from tinyspline import *
import matplotlib.pyplot as plt

spline = BSpline.interpolate_cubic_natural(
  [
     100, -100, # P1
    -100,  200, # P2
     100,  400, # P3
     400,  300, # P4
     700,  500  # P5
  ], 2) # <- dimensionality of the points

# Draw spline as polyline.
points = spline.sample(100)
x = points[0::2]
y = points[1::2]
plt.plot(x, y)

# Draw point at knot 0.3.
vec2 = spline.eval(0.3).result_vec2()
plt.plot(vec2.x, vec2.y, 'ro')

# Draw tangent at knot 0.7.
pos = spline(0.7).result_vec2() # operator () -> eval
der = spline.derive()(0.7).result_vec2().normalize() * 200
s = pos - der
t = pos + der
plt.plot([s.x, t.x], [s.y, t.y])

# Draw 15 normals with equidistant distribution.
knots = spline.equidistant_knot_seq(15)
frames = spline.compute_rmf(knots)
for i in range(frames.size()):
    pos = frames.at(i).position
    nor = pos + frames.at(i).normal * 20
    # You can also fetch the tangent and binormal:
    #     frames.at(i).tangent
    #     frames.at(i).binormal
    plt.plot([pos.x, nor.x], [pos.y, nor.y], 'g')

plt.show()

Result:

Getting Started

Documentation

The latest Doxygen documentation can be found at: https://msteinbeck.github.io/tinyspline/

The documentation of the C interface (https://msteinbeck.github.io/tinyspline/tinyspline_8h.html) is quite extensive and also serves as an entry point for the C++ interface documentation (as well as the documentation for the bindings created from the C++ interface).

Publications

If you use TinySpline in your research, please cite it as below.

@INPROCEEDINGS{Steinbeck:SANER:21,
  author =       {Steinbeck, Marcel and Koschke, Rainer},
  booktitle =    {2021 IEEE International Conference on Software
                  Analysis, Evolution and Reengineering (SANER)},
  title =        {TinySpline: A Small, yet Powerful Library for
                  Interpolating, Transforming, and Querying NURBS,
                  B-Splines, and Bézier Curves},
  year =         {2021},
  pages =        {572-576},
  doi =          {10.1109/SANER50967.2021.00068}
}

Other publications:

@INPROCEEDINGS{Steinbeck:VISSOFT:22,
  author =       {Steinbeck, Marcel and Koschke, Rainer},
  booktitle =    {2022 Working Conference on Software Visualization
                  (VISSOFT)},
  title =        {Edge Animation in Software Visualization},
  year =         {2022},
  pages =        {63-74},
  doi =          {10.1109/VISSOFT55257.2022.00015}
}

Theoretical Backgrounds

[1] is a very good starting point for B-Splines.

[2] explains De Boor's Algorithm and gives some pseudo code.

[3] provides a good overview of NURBS with some mathematical background.

[4] is useful if you want to use NURBS in TinySpline.

tinyspline's People

Contributors

cbugk avatar egradman avatar giorgiomarcias avatar giumas avatar gnimuc avatar ilgarlunin avatar jcelerier avatar julianoes avatar justinthomas avatar kwikius avatar luzpaz avatar madebr avatar marco-langer avatar msteinbeck avatar queengooborg avatar trikko avatar usuairo avatar vanxining avatar wmamrak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinyspline's Issues

Building without GL

Can tinyspline be built without OpenGL headers such as gl.h?

I'm getting the error: GL/gl.h file not found

on Xcode and OS X 10.10.

What method is being used for interpolation?

Hello,

I'm coming across some weird things when I create a Spline through interpolation. Is there a good reference that talks about how TinySpline is doing its interpolation?

Add further interpolation types

TinySpline provides natural spline interpolation only. We should add closed, periodic, and knot-a-knot interpolation in order to provide a more convenient interface.

Provide hash code function

Most high level programming languages expect a 'hash code' function if an 'equals' function is defined. Unfortunately hashing floats is not the best idea. If implemented, the hash function could only make usage of deg, order, n_ctrlp and n_knots.

Does AutoCad use this NURB formula?

I was trying to use tinyspline's NURB functions to calculate the points for the splines in DXF files that do not have "fit points", and it works for some of the splines, but not others. I was wondering if anybody knows if this is the same formula that AutoCad uses for splines, or if I'm doing something wrong.

I could give examples of splines that work and/or don't work if anybody is interested.

I have looked on AutoCad forums and the Internet for information on how AutoCad calculates points on splines, but I can't find any explanation or source code for what AutoCad does.

How do you get cartesian coordinates?

I'm trying to use this library, but I need to deal with cartesian coordinates (particularly of Beziers).

How do I get cartesian coordinates in this library?

Properly copy the python interface on MSVC

According to @giumas, the copy task of the Python binding's interface file does not work properly on MSVC since:

the library goes under "Debug" or "Release" folders.

This bug also affects setup.py as the install script assumes that all relevant files are available in a single directory.

How to get curvature

Hi Marcel

I have a set of WGS84 coordiantes, and I use the coordinates to generate a Bspline line, how could I get the curvature and corresponding coordinate? I could use derive() twice to get the curvature, but I don't know how can I get the relation between coordinate and curvature?
Besides, what's the meaning of control point and knots for the bspline line generated by derive()?

Kind regards,
Luffy

Remove TsFloatList from python wrapper

Hello,

I've started looking into using tinyspline in a future project of mine. Sorry if this issue is off-base. I'm still getting my mind around the library.

Is there a reason for using TsFloatList in tinysplinepython.i? SWIG can wrap std:: just fine.

ts_internal_bspline_thomas_algorithm have invalid access

The application could crash when using ts_bspline_interpolate() to interpolate a curve.

The code to access to variable 'm' in ts_internal_bspline_thomas_algorithm() has a buffer overflow

/* m_0 = 1/4, m_{k+1} = 1/(4-m_k), for k = 0,...,n-2 /
const size_t len_m = n-2; /
n >= 3 implies n-2 >= 1 /
float
m = malloc(len_m*size_flt);
if (m == NULL)
return TS_MALLOC;
m[0] = 0.25f;
for (i = 1; i < len_m+1; i++) //m[len_m+1] is an invalid memory address.
m[i] = 1.f/(4 - m[i-1]);

ts_bspline_to_beziers leaks on invalid data

Bug: If you pass invalid data to ts_bspline_to_beziers it leaks the memory allocated within the 'beziers' pointer.

Possible resolution: Replace 'ts_bspline_default' with 'ts_bspline_free' inside ts_bspline_to_beziers itself.

More info: ts_bspline_to_beziers calls ts_internal_bspline_copy which allocates memory to the 'beziers' struct. Eventually ts_internal_bspline_find_u is called which does some validity checking and throws if anything is invalid. The throw is caught by the handler in ts_bspline_to_beziers which clears the beziers struct instead of freeing it.

Point dimensions

Hey Marcel

Just a small question =)

I'd like to pass points with 4 dimensions of informations, such as points in 3-dimensional space and a velocity at the control points. Is it possible to interpolate all 4 dimensions, and are there priorities set by the algorithm?

Best regards,
Renato

TsBSpline.setDeg and TsBSpline.setOrder can put TsBSpline into an inconsistent state

For B-spline curves, the following relationship must hold:
degree + number_of_knots + 1 = number_of_control_points

If you allow the user to change the degree of the curve, you must also change the number of knots or number of control points. Right now, that isn't happening. In the interest of simplifying the class, it seems to me that setOrder and setDeg shouldn't exist.

Precision

Hi Marcel

Another question: I have source data which needs double precision. I have seen that there is a definition for max. relative and absolute errors. If I would change everything to double and change the precision accordingly, do I get some problems with that?

Kind regards,
Renato

indexOf/contains of bindings

TinySpline maps C float arrays into float collections (according to the binding). Some collections provide methods like 'indexOf' or 'contains'. Currently they use == to compare elements. Maybe using ts_fequals is the better choice?

ld: symbol(s) not found for architecture x86_64 on Xcode 6.4 and Apple LLVM 6.1

So I generated a Xcode project using CMake with default options.

Opening the project for building in Xcode, I noticed that I couldn't build "install" (because of it wanting gl.h headers, which I don't have).
So I built "shared", which generated the .dylib file of the library.

However, upon using this .dylib I'm confronted with error:
ld: symbol(s) not found for architecture x86_64
coming from LLVM.

Setup: Xcode 6.4 and Apple LLVM 6.1.

Any ideas if it's something wrong with how your library builds for OSX, or perhaps my setup?

Just doing #include compiles fine, but the ld: error comes when one tries to actually use the functions.

Copy operator in C++

The copy operators should check that the operands are not the same object, i.e.:

ts::DeBoorNet& ts::DeBoorNet::operator=(const ts::DeBoorNet& other)
{
    if (&other != this) {
        const tsError err = ts_deboornet_copy(&other.deBoorNet, &deBoorNet);
        if (err < 0)
            throw std::runtime_error(ts_enum_str(err));
    }
    return *this;
}

The same holds for

BSpline& operator=(const BSpline& other);

C++ shared library on MSVC

As described here:

The compilers on Linux/UNIX have the ability to export all symbols in a shared library automatically. On Windows, you must either use compiler directives __declspec(import) and __declspec(export) to declare which symbols are exported/imported from a shared library, or you must create a module definition text file (.def) with a list of all the symbols you want to export and pass that file to the linker.

To get this feature, the minimum CMake version should be bumped to 3.4. Or do you prefer to add the compiler directives?

Error handling

Simplify error handling by introducing an enum which contains the return values.

Improve Documentation

Currently the interface of TinySpline is not very well documented. I really need to fix this.

Triangle example with NURBS instead of knot insertion

@giumas wrote:

I have a question on the topic.. Is it possible to do something similar using NURBS? Isn't the intent of the R in NURBS for something like this?

Maybe it is possible but I'm not much experienced with NURBS (TinySpline provides NURBS by using Homogeneous coordinates). However, there is an answer on stackoverflow that depicts the effect of different weight values for the same control point. This figure somehow reminds me of your question :).

I can try to find a solution using NURBS instead of the knot insertion if you wish.

Adding support for Visual Studio

Visual Studio does not support the used compiler flags. The CMake files must be able to detect the Visual Studio compiler and use alternative flags. This is related to both, the C and the C++ flags.

Possible memory leak

Excuse me if I'm incorrect.

void ts_bspline_free(tsBSpline* bspline) { if (bspline->ctrlp != NULL) free(bspline->ctrlp); ts_bspline_default(bspline); }

In this function, knots are not de-allocated. Am I right that this is leaking memory?

Tinyspline to PyPi for easy installation using pip

Installing python packages using pip from pypi (https://pypi.python.org) has become the most common way to install python packages. It would make it much easier to start using tinyspline if tinyspline would be available from PyPi.

Steps to reproduce:

pip install tinyspline

Expected results:

Collecting tinyspline
  Downloading tinyspline (123kB)
Installing collected packages: tinyspline
  Running setup.py install for tinyspline
Successfully installed tinyspline

Actual results:

Collecting tinyspline
  Could not find a version that satisfies the requirement tinyspline (from versions: )
No matching distribution found for tinyspline

Interpolation not passing through supplied points?

I'm trying to use tinyspline for the first time to do some cubic spline interpolation. Very excited to use your library! Please help me understand what I'm doing wrong.

Input 2D data points are:
{-1, 0.5}, {0, 0}, {3, 3}

Calling:
ts_bspline_interpolate(points, 3, 2, &spline);

When I evaluate knots from 0.0 to 1.0 with ts_bspline_evaluate() it appears that the interpolated values pass through the first and last point but don't reach the second point at {0, 0}. It should, shouldn't it?

Knot: 0.000 Result: -1.000 0.500
Knot: 0.050 Result: -0.875 0.438
Knot: 0.100 Result: -0.748 0.380
Knot: 0.150 Result: -0.618 0.329
Knot: 0.200 Result: -0.484 0.290
Knot: 0.250 Result: -0.344 0.266
Knot: 0.300 Result: -0.196 0.260
Knot: 0.350 Result: -0.039 0.277
Knot: 0.400 Result: 0.128 0.320
Knot: 0.450 Result: 0.307 0.393
Knot: 0.500 Result: 0.500 0.500
Knot: 0.550 Result: 0.707 0.643
Knot: 0.600 Result: 0.928 0.820
Knot: 0.650 Result: 1.161 1.027
Knot: 0.700 Result: 1.404 1.260
Knot: 0.750 Result: 1.656 1.516
Knot: 0.800 Result: 1.916 1.790
Knot: 0.850 Result: 2.182 2.079
Knot: 0.900 Result: 2.452 2.380
Knot: 0.950 Result: 2.725 2.688
Knot: 1.000 Result: 3.000 3.000

Will supply any additional information as needed.

Build instructions lead to clang: error: argument unused during compilation: '-ansi' on OSX

Following:
https://github.com/retuxx/tinyspline#installation

Leads to error:

make
Scanning dependencies of target tinyspline_shared
[ 7%] Building C object library/CMakeFiles/tinyspline_shared.dir/tinyspline.c.o
[ 14%] Linking C shared library libtinyspline.dylib
clang: error: argument unused during compilation: '-ansi'
make[2]: *** [library/libtinyspline.dylib] Error 1
make[1]: *** [library/CMakeFiles/tinyspline_shared.dir/all] Error 2
make: *** [all] Error 2

on OSX 10.10 (Xcode 6.4 installed).

Unsupported binding for Python 2.7 on Windows

CPython 2.7 uses Visual Studio 2008 on Windows. Given that this compiler has a very limited support for C++11, is the Python binding for tinyspline available on Python 2.7 for Windows? Is somebody using the tinyspline package on such a configuration? If yes, how?

Structure the example module

Currently, all examples are placed in example. However, I would like to add more examples for C++, Java, etc. in future. Thus, we should create submodules within example similar to the approach used in the units-tests branch. That is, each language gets its own module in example, for instance, example/c, example/cpp, example/java, and so on.

Furthermore, @giumas suggested to rename example into examples. I'm fine with both. Are there best practices for this?

Add example of using the python bindings to the documentation

Since the documentation is sparse, some examples would really help in getting started. For example how to turn a list of control points (x,y,z) into a list of points on the spline.

from tinyspline import TsBSpline as BSpline
from tinyspline import TS_CLAMPED as CLAMPED

def points_on_spline_from_control_points(control_points, point_count=10, spline_degree=3):
    # Create a spline
    spline = BSpline(spline_degree, len(control_points[0]), len(control_points), CLAMPED)

    # Add control points to spline
    for point_idx, point in enumerate(control_points):
        point_offset = point_idx*spline.dim
        for dim_idx, val in enumerate(point):
            spline.ctrlp[point_offset + dim_idx] = val

    # Gather results
    result = []
    step_size = 1.0/(point_count-1)
    for i in range(point_count):
        deboornet = spline.evaluate(i*step_size)
        result.append(tuple(deboornet.result))
    return result

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.