fitted-curve 2 points and 2 end-vectors gives wrong result
Created by: reiniervandijk
If user makes fitted-curve with 2 points as input and 2 vectors controlling directions at start and end, object falsely assumes a linear curve. Instead, a curve of degree 3 can be fitted that gives perfect results. In the legacy ICAD platform I remember using this a lot.
Issue is in native-curve slot, this is the solution:
(native-curve
(progn
(when (and (the vectors)
(member (the vector-type) (list :tangents :normals))
(not (= (length (the points)) (length (the vectors)))))
(error "For fitted-curve ~s, points and vectors must be lists of the same length.~%"
(cons 'the (reverse (the root-path)))))
;; RvD: new condition
(cond ((and (= (length (the points)) 2)
(the vectors))
(interpolate-curve
*geometry-kernel* (the effective-points) 3 (the parameterization) :vectors (the effective-vectors)
:vector-type (the vector-type) :interpolant? (the interpolant?)
:knot-multiplicity (the knot-multiplicity)
:tolerance (the tolerance)))
((> (length (the points)) 2)
(let ((degree-ok? (<= (the degree) (1- (length (the points))))))
(unless degree-ok?
(error "The degree of a fitted-curve must be less than or equal to the number of control points."))
(interpolate-curve
*geometry-kernel* (the effective-points) (the degree) (the parameterization) :vectors (the effective-vectors)
:vector-type (the vector-type) :interpolant? (the interpolant?)
:knot-multiplicity (the knot-multiplicity)
:tolerance (the tolerance))))
(t (the linear-curve native-curve)))))
Try now the following test object and see the result:
(define-object fitted-curve-test (base-object)
:computed-slots
((points '(#(0.0 0.0 0.0)
#(1.0 0.0 0.0)))
)
:objects
((straight :type 'fitted-curve
:pass-down (points))
(works :type 'fitted-curve
:pass-down (points)
:vector-type :tangents
;;:degree 1
:vectors '(#(0.0 1.0 0.0)
#(0.0 -1.0 0.0)))
(works2 :type 'fitted-curve
:pass-down (points)
:degree 3
:vector-type :tangents
:vectors '(#(0.0 1.0 0.0)
#(0.0 -1.0 0.0)))))
Imported comments:
By genworks on 2013-02-07 06:38:10 UTC
There are actually several issues similar to this, where curve operations degenerate for curves with only two control points and/or degree of 1. Typically the problems show up with simple linear curves. For example the minimum-distance-to-curve function of curve will fail if one or both of the arguments is a curve with only two control points.
The workaround (as you refer to above) is to make an equivalent degree-3 curve with the missing control-points explicitly added. For linear-curves it is enough to make a b-spline-curve with the start and end control-points repeated, i.e. (start start end end).
We will leave this issue open until we have a general solution which makes the issue transparent.
By reiniervandijk on 2013-02-07 10:16:19 UTC
I understand. Beware though that I was not touching upon this general issue, but upon the current fitted-curve implementation that falsely makes a linear-curve object if there are 2 points given. It's about this part:
(if (not (> (length (the points)) 2)) (the linear-curve native-curve)))))
I hope I made clear that there exists a perfectly possible input from the user where he/she gives only two points plus two tangency conditions. I personally wanted to use this feature to blend some curves between other curves, satisfying continuity. Hence, my message does not provide a work-around, but provides a solution to an issue in the fitted-curve object.
By genworks on 2015-01-30 23:04:39 UTC
moving to internal tracking list.