Skip to content

curveVertex() calls are unaffected by curveTightness, even though regular curve() does work properly #13

@golanlevin

Description

@golanlevin

Wow, a serious bug-of-omission was discovered by my student, Tippi Li.

Summary:

  • curveVertex() calls are unaffected by curveTightness
  • curve() calls are correctly affected by curveTightness

Discussion

When invoking the regular curve() function, the overrideCurveFunction() adjusts all control points for curveTightness using the adjustControlPointsForTightness() function, ON THE WAY IN — prior to pushing them to the stack (see lines 359-368)

	// Adjust control points based on the current tightness setting
	const [adjX1, adjY1, adjX2, adjY2, adjX3, adjY3, adjX4, adjY4] = 
		adjustControlPointsForTightness(x1, y1, x2, y2, x3, y3, x4, y4, _svgCurveTightness);
        
    x1 = adjX1; y1 = adjY1;
    x2 = adjX2; y2 = adjY2;
    x3 = adjX3; y3 = adjY3;
    x4 = adjX4; y4 = adjY4;
    let transformMatrix = captureCurrentTransformMatrix();
    _commands.push({ type: 'curve', x1, y1, x2, y2, x3, y3, x4, y4, transformMatrix });

Note that no adjustments to the control points are made ON THE WAY OUT to the SVG, e.g. in getSvgStrCurve()

HOWEVER, when using curveVertex() calls within a beginShape()/endShape() construction, the vertices are unaffected by curveTightness. This happens because these vertices are processed through the separate overrideCurveVertexFunction(), which only copes with a single (x,y) datum and lacks the necessary context (i.e. neighboring control point data) that would be necessary to call adjustControlPointsForTightness().

Repair

The logical place to put the repair is the catmullRom2bezier() function, which is invoked:

  • within the 'path' pipeline in getSvgStrPoly(), line 2393
  • within getSvgStrCurve(), line 1625

The repair would involve moving the adjustControlPointsForTightness() functionality into catmullRom2bezier(). This will need careful testing.

There are almost certainly implications of this bug-discovery for quadraticVertex() and bezierVertex() as well. Currently the bezier/quadratic control points are exported directly to SVG without any consideration of curveTightness, in lines 2371-2377 of getSvgStrPoly() when (cmd.type === 'path').

FYI: Note that p5.js handles the influence of curveTightness in endShape():
https://github.com/processing/p5.js/blob/2f3ca7dcfead3784cf312d728ce08b46268bd0f4/src/core/p5.Renderer2D.js#L834

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions