from random import random from pprint import pprint from math import sqrt def rand100(): return (random() * 100000) - 50000 class RandomCubicBezier: def __init__(self): self.start = (rand100(), rand100()) self.c1 = (rand100(), rand100()) self.c2 = (rand100(), rand100()) self.stop = (rand100(), rand100()) def compute(self, t): u = 1 - t a = tuple(c * u * u * u for c in self.start) b = tuple(c * u * u * t for c in self.c1) c = tuple(c * u * t * t for c in self.c2) d = tuple(c * t * t * t for c in self.stop) x = sum([t[0] for t in [a, b, c, d]]) y = sum([t[1] for t in [a, b, c, d]]) return (x, y) for seg_p in range(2, 7): max_error = 0 for i in range(100): rcb = RandomCubicBezier() segments = 2 ** seg_p step = 1 / segments t1 = 0 t2 = step while t1 < 1: x1, y1 = rcb.compute(t1) x2, y2 = rcb.compute(t2) dx = abs(x2 - x1) dy = abs(y2 - y1) seg_width = dx + dy sub_t = 0 while sub_t < 1: approx_x = x1 + sub_t * dx approx_y = y1 + sub_t * dy t = t1 + (sub_t * step) actual_x, actual_y = rcb.compute(t) error_x = abs(actual_x - approx_x) error_y = abs(actual_y - approx_y) error = (error_x + error_y) / seg_width if error > max_error and seg_width > 5: max_error = error sub_t += step t1 += step t2 += step print(str(segments) + " segments: " + str(max_error))