Convert a quadratic bezier to a cubic one

后端 未结 3 897
轻奢々
轻奢々 2020-12-08 06:45

What is the algorithm to convert a quadratic bezier (with 3 points) to a cubic one (with 4 points)?

相关标签:
3条回答
  • 2020-12-08 07:23

    From https://fontforge.org/docs/techref/bezier.html#converting-truetype-to-postscript:

    Any quadratic spline can be expressed as a cubic (where the cubic term is zero). The end points of the cubic will be the same as the quadratic's.

    CP0 = QP0
    CP3 = QP2

    The two control points for the cubic are:

    CP1 = QP0 + 2/3 *(QP1-QP0)
    CP2 = QP2 + 2/3 *(QP1-QP2)

    ...There is a slight error introduced due to rounding, but it is unlikely to be noticeable.

    0 讨论(0)
  • 2020-12-08 07:23

    For reference, I implemented addQuadCurve for NSBezierPath (macOS Swift 4) based on Owen's answer above.

    extension NSBezierPath {
        public func addQuadCurve(to qp2: CGPoint, controlPoint qp1: CGPoint) {
            let qp0 = self.currentPoint
            self.curve(to: qp2,
                controlPoint1: qp0 + (2.0/3.0)*(qp1 - qp0),
                controlPoint2: qp2 + (2.0/3.0)*(qp1 - qp2))
        }
    }
    
    extension CGPoint {
        // Vector math
        public static func +(left: CGPoint, right: CGPoint) -> CGPoint {
            return CGPoint(x: left.x + right.x, y: left.y + right.y)
        }
        public static func -(left: CGPoint, right: CGPoint) -> CGPoint {
            return CGPoint(x: left.x - right.x, y: left.y - right.y)
        }
        public static func *(left: CGFloat, right: CGPoint) -> CGPoint {
            return CGPoint(x: left * right.x, y: left * right.y)
        }
    }
    
    0 讨论(0)
  • 2020-12-08 07:30

    Just giving a proof for the accepted answer.

    A quadratic Bezier is expressed as:

    Q(t) = Q0 (1-t)² + 2 Q1 (1-t) t + Q2

    A cubic Bezier is expressed as:

    C(t) = C0 (1-t)³ + 3 C1 (1-t)² t + 3 C2 (1-t) t² + C3

    For those two polynomials to be equals, all their polynomial coefficients must be equal. The polynomials coefficents are obtained by developing the expressions (example: (1-t)² = 1 - 2t + t²), then factorizing all terms in 1, t, t², and t³:

    Q(t) = Q0 + (-2Q0 + 2Q1) t + (Q0 - 2Q1 + Q2) t²

    C(t) = C0 + (-3C0 + 3C1) t + (3C0 - 6C1 + 3C2) t² + (-C0 + 3C1 -3C2 + C3) t³

    Therefore, we get the following 4 equations:

    C0 = Q0

    -3C0 + 3C1 = -2Q0 + 2Q1

    3C0 - 6C1 + 3C2 = Q0 - 2Q1 + Q2

    -C0 + 3C1 -3C2 + C3 = 0

    We can solve for C1 by simply substituting C0 by Q0 in the 2nd row, which gives:

    C1 = Q0 + (2/3) (Q1 - Q0)

    Then, we can either continue to substitute to solve for C2 then C3, or simply say "by symmetry", and conclude:

    C0 = Q0

    C1 = Q0 + (2/3) (Q1 - Q0)

    C2 = Q2 + (2/3) (Q1 - Q2)

    C3 = Q2

    0 讨论(0)
提交回复
热议问题