Here is what I have found so far. I hope it will help you.
First I added visualization of the tangents along the curve. These are the tiny red arrows. In this way, I got confirmation that one of the tangents (near the top) is wrong, as it points in a drastically different direction than the others:
Then I found that inside morph()
you loop through array t[...]
. However, it contains wrong values for the top front. For example, these lines:
g.curve.getTangent( g.t[ idx * 3 ], tangent );
console.log( idx, g.t[ idx * 3 ] ); // added by me
produce:
16 1.0018504347826087
17 1.0018504347826087
...
31 1.0018504347826087
So, the code tries to get a tangent at position beyond 1, while the curve is defined only in range [0,1].
When I add “protection” for out-of-range values, the top of the cylinder looks fine:
g.curve.getTangent( Math.min(g.t[ idx * 3],1) , tangent ); // added Math.min
My conclusion is that the out-of-range values in array t[...]
cause the problem. The wrong values are generated by a call to makeBoundaryFront( g.top, g.div4Top, -g.phiTop, -1 )
, so maybe this is the place where the error is caused.
An easy fix could be to clamp the relative height in makeBoundaryFront
:
g.t.push( THREE.MathUtils.clamp( (y-g.cylBtm )/g.height,0,1), ... );
but a better solution would be to generate only good values without clamping.