1

I am trying to draw hermit curve on canvas browser. Hermite curve is defined in terms of 2 points and 2 derivatives.

Point1X = 71
Point1Y = 165
Deriv1X = -12
Deriv1Y = 2
Point2X = 210
Point2Y = 153
Deriv2X = 108
Deriv2Y = 0

I can draw just bezier curves on canvas. Is there any way i can convert points and derivations of hermite curve to bezier curve so i can draw it on canvas?

Is there another option that i can draw hermite curve on browser?

Thanks for help.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
  • 1
    Please provide a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example of your attempt, so we can try to solve your problem and explain why your own attempt failed - that way you can learn something useful for your future development, as well as getting an answer to this single problem. – SAMUEL Mar 03 '17 at 09:22
  • This [Fiddle](http://jsfiddle.net/jmchen/m9k8qn0v/1/) may throw some light. – SAMUEL Mar 03 '17 at 09:22
  • [Here](http://stackoverflow.com/a/15528789/1693593) is a Catmull-Rom implementation with tension (aka cardinal spline). –  Mar 03 '17 at 22:13

2 Answers2

0

Canvas2d has no support for arbitrary Hermite splines, but it does support cubic Bezier curves, and since cubic Beziers are 2nd order Hermite curves, we can freely convert between your data and a Bezier curve.

The maths to do this can be found over on this Primer on Bezier curves, and specifically for this problem we can convert the Hermite points ordered [p1, d1, p2, d2] as:

Hermite points [p1,d1,p2,d2] = Bezier [p1, (p1 + d1/(2*t)), (p2 - d2/(2*t)), p2]

Note that the t value is the curve tension and controls the order of curvature at each point (the higher the tension, the higher the rate of change in curvature along the curve near the on-curve point), in this case simply 1.

(without a tension value, your four coordinates actually define an hourglass hexagonal area on the plane, rather than a single curve, as the directional vectors are not guaranteed to be true tangents; merely vectors representing the direction of travel. The area these values define is bounded by the line {start, end} on one side, with infinitely extending boundaries along the directions of travel at the start and end).

So with that, you can draw any Hermite curve on the canvas on the canvas, using the Canvas2d API for cubic Bezier curves:

// Hermite data
var p1 = ..., d1 = ..., p2 = ..., d2 = ...;
var cmpoints = [p1.x, p1.y, d1.x, d1.y, p2.x, p2.y, d2.x, d2.y];

// Bezier data
var tension = 1;
var tensionFactor = 2 * tension;
var bpoints = [
  p1.x,
  p1.y,
  p1.x + d1.x/tensionFactor,
  p1.y + d1.y/tensionFactor,
  p2.x - d2.x/tensionFactor,
  p2.y - d2.y/tensionFactor,
  p2.x,
  p2.y
]

// Draw code (where we assume you already
// have your canvas context as "ctx")
ctx.beginPath();
ctx.moveTo.apply(bpoints.slice(0,2));
ctx.bezierCurveTo.apply(bpoints.slice(2);
ctx.stroke();
Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
-1

Cubic Hermite curve (defined by C(0), C'(0), C(1) and C'(1)) and cubic Bezier curve (defined by P0, P1, P2, and P3) can be related to each other by

C(0) = P0,
C(1) = P3,
C'(0) = 3(P1-P0),
C'(1) = 3(P3-P2)

Therefore, you can find the control points as

P0=C(0),
P1=(1/3)*C'(0)+P0,
P2=P3-(1/3)*C'(1),
P3=C(1)

fang
  • 3,473
  • 1
  • 13
  • 19