Skip to content

remove_knot implementation bug #135

@portnov

Description

@portnov

Describe the bug
remove_knot() method returns a curve, which is geometrically different from original curve. According to description of this operation (see The NURBS Book, p.5.4), the resulting curve should be geometrically and parametrically identical to original one

To Reproduce

from math import sqrt

import geomdl
from geomdl import operations, BSpline

curve = BSpline.Curve()
curve.degree = 2
curve.ctrlpts = [[0, 0, 0], [1, 1, 0], [2, 0, 0]]
curve.knotvector = [0, 0, 0, 1, 1, 1]

ts = [0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0]

inserted = BSpline.Curve()
inserted.degree = curve.degree
inserted.ctrlpts = curve.ctrlpts
inserted.knotvector = curve.knotvector
inserted.insert_knot(0.5, num=1)

removed = BSpline.Curve()
removed.degree = inserted.degree
removed.ctrlpts = inserted.ctrlpts
removed.knotvector = inserted.knotvector
removed.remove_knot(0.5, num=1)

tolerance = 1e-5

def distance(pt1, pt2):
    x1, y1, z1 = pt1
    x2, y2, z2 = pt2

    return sqrt((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2)

print("Insertion:")
for t in ts:
    orig = curve.evaluate_single(t) 
    new = inserted.evaluate_single(t)
    print(f"T = {t}, orig = {orig}, new = {new}")
    if distance(orig, new) > tolerance:
        raise Exception("Too far")

print("Removal:")
for t in ts:
    orig = curve.evaluate_single(t) 
    new = removed.evaluate_single(t)
    print(f"T = {t}, orig = {orig}, new = {new}")
    if distance(orig, new) > tolerance:
        raise Exception("Too far")

Output:

Insertion:
T = 0, orig = [0.0, 0.0, 0.0], new = [0.0, 0.0, 0.0]
T = 0.1, orig = [0.2, 0.18000000000000002, 0.0], new = [0.20000000000000004, 0.18000000000000005, 0.0]
T = 0.3, orig = [0.6, 0.42, 0.0], new = [0.6, 0.41999999999999993, 0.0]
T = 0.5, orig = [1.0, 0.5, 0.0], new = [1.0, 0.5, 0.0]
T = 0.7, orig = [1.4, 0.42000000000000004, 0.0], new = [1.4, 0.42000000000000004, 0.0]
T = 0.9, orig = [1.8, 0.17999999999999997, 0.0], new = [1.8000000000000003, 0.18, 0.0]
T = 1.0, orig = [2.0, 0.0, 0.0], new = [2.0, 0.0, 0.0]
Removal:
T = 0, orig = [0.0, 0.0, 0.0], new = [0.0, 0.0, 0.0]
T = 0.1, orig = [0.2, 0.18000000000000002, 0.0], new = [0.29000000000000004, 0.09000000000000001, 0.0]
Traceback (most recent call last):
  File "/home/portnov/src/sverchok/test.py", line 49, in <module>
    raise Exception("Too far")
Exception: Too far

Metadata

Metadata

Assignees

Labels

bugThere is a problem with the code or documentation

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions