This page contains all the documentation of the classes and methods.
- class nurbs.GeneratorKnotVector[source]
Set of static functions to help creating KnotVector of given
degreeandnpts- static bezier(degree: int, cls: type | None = <class 'int'>) KnotVector[source]
Creates the KnotVector of a bezier curve.
- Parameters:
degree (int) – The degree of the bezier curve, non-negative
cls (int(, optional)) – The class to convert the number, defaults to
int
- Raises:
AssertionError – If
degreeis not a non-negative integer- Returns:
The bezier knot vector
- Return type:
Example use
>>> from compmec.nurbs import GeneratorKnotVector >>> GeneratorKnotVector.bezier(1) (0, 0, 1, 1) >>> GeneratorKnotVector.bezier(2) (0, 0, 0, 1, 1, 1) >>> GeneratorKnotVector.bezier(3) (0, 0, 0, 0, 1, 1, 1, 1) >>> GeneratorKnotVector.bezier(3, float) (0., 0., 0., 0., 1., 1., 1., 1.)
- static integer(degree: int, npts: int, cls: type | None = <class 'int'>) KnotVector[source]
Creates a KnotVector of equally integer spaced.
- Parameters:
degree (int) – The degree of the curve, non-negative
npts (int) – The number of control points of the curve
cls (int(, optional)) – The class to convert the number, defaults to
int
- Raises:
AssertionError – If
degreeornptsis not a non-negative integerAssertionError – If
nptsis not greater thandegree
- Returns:
The bezier knot vector
- Return type:
Example use
>>> from compmec.nurbs import GeneratorKnotVector >>> GeneratorKnotVector.integer(1, 2) (0, 0, 1, 1) >>> GeneratorKnotVector.integer(1, 3) (0, 0, 1, 2, 2) >>> GeneratorKnotVector.integer(2, 5) (0, 0, 0, 1, 2, 3, 3, 3) >>> GeneratorKnotVector.integer(2, 5, float) (0., 0., 0., 1., 2., 3., 3., 3.)
- static uniform(degree: int, npts: int, cls: type | None = <class 'int'>) KnotVector[source]
Creates a equally distributed knotvector between [0, 1]
- Parameters:
degree (int) – The degree of the curve, non-negative
npts (int) – The number of control points of the curve
cls (int(, optional)) – The class to convert the number, defaults to
int
- Raises:
AssertionError – If
degreeornptsis not a non-negative integerAssertionError – If
nptsis not greater thandegree
- Returns:
The uniform knotvector of given degree and number of control points
- Return type:
Example use
>>> from fractions import Fraction >>> from compmec.nurbs import GeneratorKnotVector >>> GeneratorKnotVector.uniform(1, 2) (0, 0, 1, 1) >>> GeneratorKnotVector.uniform(1, 3) (0, 0, 0.5, 1, 1) >>> GeneratorKnotVector.uniform(2, 6) (0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1) >>> GeneratorKnotVector.uniform(1, 3, Fraction) (Fraction(0, 1), Fraction(0, 1), Fraction(1, 2), Fraction(1, 1), Fraction(1, 1))
- static random(degree: int, npts: int, cls: type | None = <class 'float'>) KnotVector[source]
Creates a random distributed knotvector between [0, 1]
- Parameters:
degree (int) – The degree of the curve, non-negative
npts (int) – The number of control points of the curve
cls (float(, optional)) – The class to convert the number, defaults to
float
- Raises:
AssertionError – If
degreeornptsis not a non-negative integerAssertionError – If
nptsis not greater thandegree
- Returns:
The random knotvector of given degree and number of control points
- Return type:
Example use
>>> from compmec.nurbs import GeneratorKnotVector >>> GeneratorKnotVector.random(1, 2) (0, 0, 1, 1) >>> GeneratorKnotVector.random(1, 3) (0, 0, 0.4, 1, 1) >>> GeneratorKnotVector.random(2, 6) [0, 0, 0, 0.21, 0.57, 0.61, 1, 1, 1]
- static weight(degree: int, weights: Tuple[float]) KnotVector[source]
Creates a knotvector of degree
degreebased on givenweightsvector.- Parameters:
degree (int) – The degree of the curve, non-negative
weights (tuple[float]) – The vector of weights
- Raises:
AssertionError – If
degreeis not a non-negative integerAssertionError – If the weights is not an array of positive numbers
- Returns:
A knotvector of degree
degree- Return type:
Example use
>>> from compmec.nurbs import GeneratorKnotVector >>> GeneratorKnotVector.weights(1, [1]) (0, 0, 1, 1) >>> GeneratorKnotVector.weights(2, [1]) (0, 0, 0, 1, 1, 1) >>> GeneratorKnotVector.weights(2, [2]) (0, 0, 0, 2, 2, 2) >>> GeneratorKnotVector.weights(1, [2, 2]) (0, 0, 2, 4, 4) >>> GeneratorKnotVector.weights(1, [1, 2]) (0, 0, 1, 3, 3) >>> GeneratorKnotVector.weights(1, [1., 2.]) (0., 0., 1., 3., 3.)
- class nurbs.KnotVector(vector: Tuple[float], degree: int | None = None)[source]
Creates a KnotVector instance
Examples
>>> KnotVector([0, 1]) (0, 1) >>> KnotVector([0, 0, 1, 1]) (0, 0, 1, 1) >>> KnotVector([0, 0, 0.5, 1, 1]) (0, 0, 0.5, 1, 1)
- property npts: int
Number of control points
- Getter:
Returns the number of control points
- Type:
int
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0., 1.]) >>> knotvector.npts 1 >>> knotvector = KnotVector([1, 1, 2, 3, 3]) >>> knotvector.npts 3
- property knots: Tuple[float]
Non-repeted knots
- Getter:
Non-repeted knots
- Type:
tuple[float]
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0., 1.]) >>> knotvector.knots (0., 1.) >>> knotvector = KnotVector([1, 1, 2, 3, 3]) >>> knotvector.knots (1, 2, 3) >>> knotvector = KnotVector([0, 0, 0, 1, 2, 2, 3, 3, 3]) >>> knotvector.knots (0, 1, 2, 3)
- property limits: Tuple[float]
The knotvector limits
- Getter:
Returns the tuple [Umin, Umax]
- Type:
tuple[float]
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0., 1.]) >>> knotvector.limits (0., 1.) >>> knotvector = KnotVector([1, 1, 2, 3, 3]) >>> knotvector.degree (1, 3)
- property degree: int
Polynomial degree
- Getter:
Returns the degree of the curve
- Setter:
Increases or decreases curve’s degree
- Type:
int
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0., 1.]) >>> knotvector.degree 0 >>> knotvector.degree = 1 >>> print(knotvector) (0., 0., 1., 1.) >>> knotvector = KnotVector([1, 1, 2, 3, 3]) >>> knotvector.degree 1 >>> knotvector.degree = 3 >>> print(knotvector) (1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3)
- property internal: ImmutableKnotVector
Internal immutable knotvector
- Getter:
Returns the immutable knot vector instance
- Setter:
Sets as new knot vector instance
- Type:
ImmutableKnotVector
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0., 1.]) >>> knotvector.internal (0., 1.)
- shift(value: float) KnotVector[source]
Add
valueto each knot- Parameters:
value (float) – The amount to shift every knot
- Raises:
TypeError – If
valueis not a number- Returns:
The same instance
- Return type:
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0, 0, 1, 1]) >>> knotvector.shift(1) (1, 1, 2, 2) >>> knotvector.shift(-1) (0, 0, 1, 1) >>> knotvector.shift(1.0) (1., 1., 2., 2.) >>> knotvector += 1 # same as shift(1) (2., 2., 3., 3.) >>> knotvector -= 1 # same as shift(-1) (1., 1., 2., 2.)
- scale(value: float) KnotVector[source]
Multiplies every knot by amount
value- Parameters:
value (float) – The amount to scale every knot
- Raises:
TypeError – If
valueis not a numberAssertionError – If
valueis not positive
- Returns:
The same instance
- Return type:
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([1, 1, 2, 2]) >>> knotvector.scale(2) (2, 2, 4, 4) >>> knotvector *= 2 # same as scale(2) (4, 4, 8, 8) >>> knotvector.scale(1/2) (2., 2., 4., 4.) >>> knotvector /= 2 # same as scale(1/2) (1., 1., 2., 2.)
- convert(cls: type, tolerance: float | None = 1e-09) KnotVector[source]
Convert the knots from current type to given type.
If
toleranceis too small, it raises a ValueError cause cannot convert.- Parameters:
cls (type) – The class to convert the knots
tolerance (float) – The tolerance to check if each node is very far from other
- Raises:
ValueError – If cannot convert all knots to given type for given tolerance
- Returns:
The same instance
- Return type:
Example use
>>> from fractions import Fraction >>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([1., 1., 2., 3., 3.]) >>> knotvector.convert(int) (1, 1, 2, 3, 3) >>> knotvector.convert(float) (1., 1., 2., 3., 3.) >>> knotvector.convert(Fraction) (Fraction(1, 1), Fraction(1, 1), Fraction(2, 1), Fraction(3, 1), Fraction(3, 1)) >>> knotvector = KnotVector([0., 0., 0.5, 1., 1.]) >>> knotvector.convert(int) ValueError: Cannot convert knot 0.5 from type <class 'float'> to type <class 'int'>
- normalize() KnotVector[source]
Shift and scale the vector to match the interval [0, 1]
- Returns:
The same instance
- Return type:
Example use
>>> from fractions import Fraction >>> from compmec.nurbs import KnotVector >>> vector = [1, 1, 2, 3, 3] >>> knotvector = KnotVector(vector) >>> knotvector.normalize() (0., 0., 0.5, 1., 1.) >>> vector = [2, 2, 3, 4, 4] >>> knotvector = KnotVector(vector) >>> knotvector.convert(Fraction) >>> knotvector.normalize(Fraction) (Fraction(0, 1), Fraction(0, 1), Fraction(1, 2), Fraction(1, 1), Fraction(1, 1))
- insert(nodes: Tuple[float]) KnotVector[source]
Insert given nodes inside knotvector
- Parameters:
nodes (tuple[float]) – The nodes to be inserted
- Raises:
ValueError – If cannot insert knots
- Returns:
The same instance
- Return type:
Example use
>>> from fractions import Fraction >>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0, 0, 2, 3, 3]) >>> knotvector.insert([2]) (0, 0, 2, 2, 3, 3) >>> knotvector.insert([2]) ValueError: Cannot insert nodes [2] in knotvector (0, 0, 2, 2, 3, 3)" >>> knotvector += [1] # Same as insert([1]) (0, 0, 1, 2, 2, 3, 3)
- remove(nodes: Tuple[float]) KnotVector[source]
Remove given nodes inside knotvector
- Parameters:
nodes (tuple[float]) – The nodes to be remove
- Raises:
ValueError – If cannot remove knots
- Returns:
The same instance
- Return type:
Example use
>>> from fractions import Fraction >>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0, 0, 1, 2, 3, 3]) >>> knotvector.remove([2]) (0, 0, 1, 3, 3) >>> knotvector.remove([2]) ValueError: Cannot remove nodes [2] in knotvector (0, 0, 1, 3, 3)" >>> knotvector -= [1] # Same as remove([1]) (0, 0, 3, 3)
- span(nodes: float | Tuple[float]) int | Tuple[int][source]
Finds the index position of a
nodesuchknotvector[span] <= node < knotvector[span+1]If
nodesis a vector of numbers, it returns a vector of indexs- Parameters:
nodes (float | tuple[float]) – A node to compute the span, or a list of nodes
- Raises:
TypeError – If
nodesis not a list of numbersValueError – If at least one node is outside
[umin, umax]
- Returns:
The index of the node
- Return type:
int | tuple[int]
Example use
>>> from compmec.nurbs import KnotVector >>> vector = [0, 0, 1, 2, 2] >>> knotvector = KnotVector(vector) >>> knotvector.span(0) 1 >>> knotvector.span(0.5) 1 >>> knotvector.span(1) 2 >>> knotvector.span([0, 0.5, 1, 1.5, 2]) (1, 1, 2, 2, 2)
- mult(nodes: float | Tuple[float]) int | Tuple[int][source]
Counts how many times a node is inside the knotvector
If
nodesis a vector of numbers, it returns a list of mult- Parameters:
nodes (float | tuple[float]) – The node to count, or a list of nodes
- Raises:
TypeError – If
nodesis not a number or a list of numbersValueError – If the node is outside
[umin, umax]
- Returns:
The index of the node
- Return type:
int | tuple[int]
Example use
>>> from compmec.nurbs import KnotVector >>> vector = [0, 0, 1, 2, 2] >>> knotvector = KnotVector(vector) >>> knotvector.mult(0) 2 >>> knotvector.mult(1) 1 >>> knotvector.mult(0.5) 0 >>> knotvector.mult([0, 0.5, 1, 1.2, 1.8, 2]) (2, 0, 1, 0, 0, 2)
- valid(nodes: Tuple[float]) bool[source]
Tells if all given nodes are valid
- Parameters:
nodes (tuple[float]) – The list of nodes
- Raises:
TypeError – If
nodesis not a list of numbers- Returns:
If all the nodes are in the interval
[umin, umax]- Return type:
bool
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0, 0, 1, 1]) >>> knotvector.valid([0, 0.5, 1]) True >>> knotvector.valid([-1, 0.5, 1]) False
- split(nodes: Tuple[float]) Tuple[KnotVector][source]
Split the knot vector at given nodes
- Parameters:
nodes (tuple[float]) – The list of nodes
- Raises:
TypeError – If
nodesis not a list of numbers- Returns:
The list of splited knot vectors
- Return type:
tuple[KnotVector]
Example use
>>> from compmec.nurbs import KnotVector >>> knotvector = KnotVector([0, 0, 1, 1]) >>> knotvector.split([0.5]) ((0, 0, 0.5, 0.5), (0.5, 0.5, 1, 1))
- class nurbs.Function(knotvector: KnotVector)[source]
Basis Function class, to evaluate functions
Example use
>>> import numpy as np >>> from compmec.nurbs import Function >>> knotvector = [0, 0, 1, 1] >>> basis = Function(knotvector) >>> basis.degree 1 >>> basis.npts 2 >>> basis(0.5) # same as basis[:, degree](0.5) (0.5, 0.5) >>> basis([0, 0.5, 1]) ((0, 0.5, 1), (1, 0.5, 0))
- class nurbs.Curve(knotvector: KnotVector, ctrlpoints: ndarray | None = None, weights: ndarray | None = None)[source]
- eval(nodes: float | Tuple[float]) Any | Tuple[Any][source]
Point evaluation function
- Parameters:
nodes (float | tuple[float]) – The nodes to evaluates
- Raises:
TypeError – If
nodesis not a number or a list of numbersValueError – If at least node is outside
[umin, umax]
- Returns:
The point computed by using control points
- Return type:
Any | tuple[Any]
Example use
>>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0.5, 1, 1]) >>> curve.ctrlpoints = (1, 2, -3) >>> curve(0) 1.0 >>> curve(0.2) 1.4 >>> curve(0.5)] 2.0 >>> curve([0, 0.5, 1]) (1.0, 2.0, -3.0)
- knot_insert(nodes: Tuple[float]) None[source]
Insert given nodes inside knotvector
- Parameters:
nodes (tuple[float]) – The nodes to be inserted
- Raises:
TypeError – If
nodesis not a number or a list of numbersValueError – If it’s not possible to insert the knots
Example use
>>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0.5, 1, 1]) >>> curve.ctrlpoints = (1, 2, -3) >>> curve.knot_insert([0.2, 0.7]) >>> curve.knotvector (0, 0, 0.2, 0.5, 0.7, 1, 1)
- knot_remove(nodes: Tuple[float], tolerance: float = 1e-09) None[source]
Remove given nodes from knotvector
- Parameters:
nodes (tuple[float](, optional)) – The nodes to be removed
tolerance (float(, optional)) – Tolerance to remove knots, defaults to
1nodes – Nodes to be assure to, defaults to
None
- Raises:
TypeError – If
nodesis not a number or a list of numbersValueError – If it’s not possible to remove the knot
Example use
>>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0, 0.5, 1, 1, 1]) >>> curve.ctrlpoints = [1, 1.5, -0.5, -3] >>> print(curve) Spline curve of degree 2 and 4 control points KnotVector = (0, 0, 0, 0.5, 1, 1, 1) ControlPoints = [1, 1.5, -0.5, -3] >>> curve.knot_remove([0.5]) >>> print(curve) Bezier curve of degree 2 and 3 control points KnotVector = (0, 0, 0, 1, 1, 1) ControlPoints = [1.0, 2.0, -3.0]
- knot_clean(nodes: Tuple[float] | None = None, tolerance: float | None = 1e-09) None[source]
Remove all unnecessary knots.
If no nodes are given, it tries to remove all internal knots
Nothing happens if the curve is irreductible
Nodes equals to extremities are ignored
Nodes which are not in knotvectors are ignored
- Parameters:
nodes (tuple[float](, optional)) – The nodes to be removed, defaults to
None, all internal knotstolerance (float(, optional)) – The tolerance to remove knots, defaults to
1e-9
- Raises:
TypeError – If
nodesis not a number or a list of numbersTypeError – If
toleranceis not a numberValueError – If
toleranceis negative
Example use
>>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0, 0.5, 1, 1, 1]) >>> curve.ctrlpoints = [1, 1.5, -0.5, -3] >>> print(curve) Spline curve of degree 2 and 4 control points KnotVector = (0, 0, 0, 0.5, 1, 1, 1) ControlPoints = [1, 1.5, -0.5, -3] >>> curve.knot_clean() >>> print(curve) Bezier curve of degree 2 and 3 control points KnotVector = (0, 0, 0, 1, 1, 1) ControlPoints = [1.0, 2.0, -3.0]
- degree_increase(times: int | None = 1)[source]
Increase the degree of the curve by an amount
times- Parameters:
times (int(, optional)) – The number of times to increase, defaults to
1- Raises:
AssertionError – If
timesis not a integer >= 0
Example use
>>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0, 0.5, 1, 1, 1]) >>> curve.ctrlpoints = [1, 1.5, -0.5, -3] >>> print(curve) Spline curve of degree 2 and 4 control points KnotVector = (0, 0, 0, 0.5, 1, 1, 1) ControlPoints = [1, 1.5, -0.5, -3] >>> curve.degree_increase(1) >>> print(curve) Spline curve of degree 3 and 6 control points KnotVector = (0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1) ControlPoints = [1.0, 1.33, 1.17, -0.17, -1.33, -3.0]
- degree_decrease(times: int | None = 1, tolerance: float | None = 1e-09)[source]
Decrease the degree of the curve by an amount
times- Parameters:
times (int(, optional)) – The number of times to reduce degree, defaults to
1tolerance (float(, optional)) – Tolerance to remove knots, defaults to
1
- Raises:
AssertionError – If
timesis not a integer >= 0
Example use
>>> from compmec.nurbs import Curve >>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1]) >>> curve.ctrlpoints = [1, 4/3, 7/6, -1/6, -4/3, -3] >>> print(curve) Spline curve of degree 3 and 6 control points KnotVector = (0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1) ControlPoints = [1.0, 1.33, 1.17, -0.17, -1.33, -3.0] >>> curve.degree_decrease(1) >>> print(curve) Spline curve of degree 2 and 4 control points KnotVector = (0, 0, 0, 0.5, 1, 1, 1) ControlPoints = [1, 1.5, -0.5, -3]
- degree_clean(tolerance: float = 1e-09)[source]
Reduces au maximum the degree of the curve for given tolerance.
Does nothing if cannot reduce the degree
- Parameters:
tolerance (float(, optional)) – The tolerance to reduce degree, defaults to
1e-9- Raises:
AssertionError – If
toleranceis not a number >= 0
Example use
>>> from compmec.nurbs import Curve >>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1]) >>> curve.ctrlpoints = [1, 4/3, 7/6, -1/6, -4/3, -3] >>> print(curve) Spline curve of degree 3 and 6 control points KnotVector = (0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1) ControlPoints = [1.0, 1.33, 1.17, -0.17, -1.33, -3.0] >>> curve.degree_clean() >>> print(curve) Spline curve of degree 2 and 4 control points KnotVector = (0, 0, 0, 0.5, 1, 1, 1) ControlPoints = [1, 1.5, -0.5, -3]
- clean(tolerance: float = 1e-09)[source]
Calls degree_clean and knot_clean
If the curve is rational, it tries to simplify,
- Parameters:
tolerance (float(, optional)) – The tolerance to reduce degree, defaults to
1e-9- Raises:
AssertionError – If
toleranceis not a number >= 0
Example use
>>> from compmec.nurbs import Curve >>> from compmec.nurbs import Curve >>> curve = Curve([0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1]) >>> curve.ctrlpoints = [1, 4/3, 7/6, -1/6, -4/3, -3] >>> print(curve) Spline curve of degree 3 and 6 control points KnotVector = (0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1) ControlPoints = [1.0, 1.33, 1.17, -0.17, -1.33, -3.0] >>> curve.degree_clean() >>> print(curve) Spline curve of degree 2 and 4 control points KnotVector = (0, 0, 0, 0.5, 1, 1, 1) ControlPoints = [1, 1.5, -0.5, -3]
- split(nodes: Tuple[float] | None = None) Tuple[Curve][source]
Separate the current curve at specified nodes
If no arguments are given, it splits at every knot, returning a list of bezier curves
- Parameters:
nodes – The positions to split, defaults to
None, all internal nodes
Example use
>>> from compmec.nurbs import Curve >>> knotvector = (0, 0, 0, 0.5, 1, 1, 1) >>> ctrlpoints = [2, 1, 3, 0] >>> curve = Curve(knotvector, ctrlpoints) >>> subcurves = curve.split([0.2, 0.8]) >>> len(subcurves) 3 >>> subcurves[0].knotvector (0.0, 0.0, 0.0, 0.2, 0.2, 0.2) >>> subcurves[1].knotvector (0.2, 0.2, 0.2, 0.5, 0.8, 0.8, 0.8) >>> subcurves[2].knotvector (0.8, 0.8, 0.8, 1.0, 1.0, 1.0)
- fit_curve(other: Curve, nodes: Tuple[float] | None = None) float[source]
Finds the control points such this curve keeps as near as possible to
otherIf nodes are given
- if len(nodes) < npts
interpolates all nodes, uses least square in the other degrees of freedom
- if len(nodes) == npts
interpolate at all points
- if len(nodes) > npts:
same as fit_points(other(nodes), nodes)
- Parameters:
other (Curve) – The objective curve
nodes (None | tuple[float](, optional)) – The positions to fit, defaults to
None
Example use
>>> from compmec.nurbs import Curve >>> knotvector = (0, 0, 0, 0.5, 1, 1, 1) >>> ctrlpoints = [2, 1, 3, 0] >>> curvea = Curve(knotvector, ctrlpoints) >>> curveb = Curve([0, 0, 0.5, 1, 1]) >>> curveb.fit_curve(curvea) >>> print(curveb) Spline curve of degree 1 and 3 control points KnotVector = (0, 0, 0.5, 1, 1) ControlPoints = [1.417, 2.167, 0.917]
- fit_function(function: Callable, nodes: Tuple[float] | None = None) None[source]
Finds the control points such this curve keeps as near as possible to
function- If nodes are not given, it uses least square in many intervals
for subinterval [uk, u_{k+1}] evaluates on max(degree+1, 5*npts/len(subintervals)) using chebyshev nodes
- if len(nodes) < npts
interpolates all nodes, uses least square in the other degrees of freedom
- if len(nodes) == npts
interpolate at all points
- if len(nodes) > npts:
same as fit_points(other(nodes), nodes)
- Parameters:
other (Curve) – The objective curve
nodes (None | tuple[float](, optional)) – The positions to fit, defaults to
None
Example use
>>> from compmec.nurbs import Curve >>> knotvector = (0, 0, 0.5, 1, 1) >>> curve = Curve(knotvector) >>> function = lambda x: 1 + x**2 >>> curve.fit_function(function) >>> print(curve) Spline curve of degree 1 and 3 control points KnotVector = (0, 0, 0.5, 1, 1) ControlPoints = [0.969, 1.219, 1.969]
- fit_points(points: Tuple[Any], nodes: Tuple[float] | None = None) None[source]
Finds the control points such this curve keeps as near as possible to
pointsIf nodes are not given, it supposes equally distributed nodes
- if len(points) < npts
ValueError
- if len(nodes) == npts
interpolate at all points
- if len(nodes) > npts:
Uses discrete least squares
- Parameters:
points (tuple[any]) – The objective points
nodes (None | tuple[float](, optional)) – The positions to fit, defaults to
None, equally distributed points
Example use
>>> import numpy as np >>> from compmec.nurbs import Curve >>> knotvector = (0, 0, 0.5, 1, 1) >>> curve = Curve(knotvector) >>> function = lambda x: 1 + x**2 >>> usample = np.linspace(0, 1, 129) >>> points = function(usample) >>> curve.fit_points(points) >>> print(curve) Spline curve of degree 1 and 3 control points KnotVector = (0, 0, 0.5, 1, 1) ControlPoints = [0.96, 1.21, 1.96]
- class nurbs.calculus.Integrate[source]
- static scalar(curve: Curve, function: Callable[[float], Any] | None = None, method: str | None = None, nnodes: int | None = None) float[source]
Computes the integral I
If no
functionis given, it supposes that \(g(u)=1\)If no
method = (algo, npts)is given- If
knotvectornumber type isintorFraction npts = 1 + curve.degreealgo = "closed-newton-cotes"
- If
- Else
npts = 1 + curve.degreealgo = "chebyshev"
Valid algorithms
algoareclosed-newton-cotes,open-newton-cotes,chebyshevorgauss-legendre- Parameters:
curve (Curve) – The curve \(\mathbf{C}(u)\) to integrate
function (None | callable[[float], Any](, optional)) – The weight function \(g(u)\), defaults to
Nonemethod (None | tuple[str, int](, optional)) – The integration method, defaults to
None
- static lenght(curve: Curve, function: Callable[[float], Any] | None = None, method: str | None = None, nnodes: int | None = None) float[source]
Computes the integral I
The operation
@is needed causenorm(curve(u)) = numpy.sqrt(curve(u) @ curve(u))If no
functionis given, it supposes that \(g(u)=1\)- If
method == None: - If
knotvectornumber type isintorFraction method = "closed-newton-cotes"
- If
- Else
npts = 1 + curve.degreemethod = "chebyshev"
Valid algorithms
algoareclosed-newton-cotes,open-newton-cotes,chebyshevorgauss-legendre- Parameters:
curve (Curve) – The curve \(\mathbf{C}(u)\) to integrate
function (None | callable[[float], Any](, optional)) – The weight function \(g(u)\), defaults to
Nonemethod (None | tuple[str, int](, optional)) – The integration method, defaults to
None
- If
- static density(curve: Curve, function: Callable[[float], Any] | None = None, method: str | None = None, nnodes: int | None = None) float[source]
Computes the integral I
The operation
@is needed causenorm(curve(u)) = numpy.sqrt(curve(u) @ curve(u))If no
functionis given, it supposes that \(g(u)=1\)If no
method = (algo, npts)is given- If
knotvectornumber type isintorFraction npts = 1 + curve.degreealgo = "closed-newton-cotes"
- If
- Else
npts = 1 + curve.degreealgo = "chebyshev"
Valid algorithms
algoareclosed-newton-cotes,open-newton-cotes,chebyshevorgauss-legendre- Parameters:
curve (Curve) – The curve \(\mathbf{C}(u)\) to integrate
function (None | callable[[float], Any](, optional)) – The weight function \(g(u)\), defaults to
Nonemethod (None | tuple[str, int](, optional)) – The integration method, defaults to
None
- static function(knotvector: KnotVector, function: Callable[[float], Any] | None, method: str | None = None, nnodes: int | None = None) float[source]
Computes the integral I
\[I = \int_{a}^{b} g ( u ) \ du\]The operation
@is needed causenorm(curve(u)) = numpy.sqrt(curve(u) @ curve(u))If no
functionis given, it supposes that \(g(u)=1\)If no
method = (algo, npts)is given- If
knotvectornumber type isintorFraction npts = 1 + curve.degreealgo = "closed-newton-cotes"
- If
- Else
npts = 1 + curve.degreealgo = "chebyshev"
Valid algorithms
algoareclosed-newton-cotes,open-newton-cotes,chebyshevorgauss-legendre- Parameters:
curve (Curve) – The curve \(\mathbf{C}(u)\) to integrate
function (None | callable[[float], Any](, optional)) – The weight function \(g(u)\), defaults to
Nonemethod (None | tuple[str, int](, optional)) – The integration method, defaults to
None
- class nurbs.advanced.Projection[source]
Projection class to evaluate the nearest point/curve with respect to another point/curve
- static point_on_bezier(point: Tuple[float], bezier: Curve) Tuple[float][source]
Finds the parameters t* such bezier(t*) is the near point
- static point_on_curve(point: Tuple[float], curve: Curve) Tuple[float][source]
Finds the parameters t* such curve(t*) is near point
This function finds the parameter tstar in [tmin, tmax] such minimizes the distance abs(curve(tstar) - point).
Trully, it minimizes the distance square, related to the inner product < C(u) - P, C(u) - P > = abs(C(u)-P)^2 This function finds the solution of f(u) = < C’(u), C(u) - P > = 0
Since it’s possible to have more than one solution: for example, the center of a circle is at equal distance always then we return a list of parameters
First, we decompose the curve in beziers, and try to find the minimum distance of each bezier curve. We use Newton’s method
- class nurbs.advanced.Intersection[source]
Intersection static class, responsible to compute the intersection between two objects, like curve and curve, surface and curve, and so on
- static filter_pairs(pairs: Tuple[Tuple[float]], tolerance: float = 1e-09)[source]
Filter the repeted knots within a given tolerance
- static pairs_min_distance(pairs: Tuple[float], curvea: Curve, curveb: Curve, tolerance: float = 1e-09)[source]
Filter the pairs (t*, u*) such abs(curvea(t*) - curveb(u*)) > tolerance
- static bcurve_and_bcurve(beziera: Curve, bezierb: Curve) Tuple[float, float][source]
Return the parameters t*, u* such beziera(t*) = bezierb(u*)
Given two bezier curves, A(t) and B(u), this function returns the intersections between A and B. It can be:
If A(t) don’t touch B(u), returns empty tuple
- If A(t) touches B(u) in a finite number of points, it returns
the pairs [(ta, ua), (tb, ub), …, (tk, uk)]
- If A(t) overlaps B(u) in some interval, it returns
The interval [(ta, tb), (ua, ub)] Still needs implementation
- static curve_and_curve(curvea: Curve, curveb: Curve) Tuple[Curve][source]
Return the parameters t*, u* such curvea(t*) = curveb(u*)
Given two curves, A(t) and B(u), this function returns the intersections between A and B. It can be:
If A(t) don’t touch B(u), returns empty tuple
- If A(t) touches B(u) in a finite number of points, it returns
the pairs [(ta, ua), (tb, ub), …, (tk, uk)]
- If A(t) overlaps B(u) in some interval, it returns
The interval [(ta, tb), (ua, ub)]