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.