def newtonRaphsonRootFind(bez, point, u): """ Newton's root finding algorithm calculates f(x)=0 by reiterating x_n+1 = x_n - f(x_n)/f'(x_n) We are trying to find curve parameter u for some point p that minimizes the distance from that point to the curve. Distance point to curve is d=q(u)-p. At minimum distance the point is perpendicular to the curve. We are solving f = q(u)-p * q'(u) = 0 with f' = q'(u) * q'(u) + q(u)-p * q''(u) gives u_n+1 = u_n - |q(u_n)-p * q'(u_n)| / |q'(u_n)**2 + q(u_n)-p * q''(u_n)| """ d = bezier.q(bez, u) - point numerator = (d * bezier.qprime(bez, u)).sum() denominator = (bezier.qprime(bez, u)**2 + d * bezier.qprimeprime(bez, u)).sum() if denominator == 0.0: return u else: return u - numerator / denominator
def remove_markers(strokes_topology, intersections): strokes_array = convert_strokes_topology_to_strokes_array(strokes_topology) del_strokes = [] old_indices = [] for s_idx, s in enumerate(strokes_topology): if s["primitive_type"] == 1: # for curves, the length2D has yet to be established points = strokes_array[s_idx] bez = [ np.array(fitCurves.generate_bezier_without_tangents(points))][0] # interpolate curve interp_points = [] for t in np.arange(0.0, 1.05, 0.05): interp_points.append(bz.q(bez, t)) curve = LineString(np.array(interp_points)) s["length2D"] = curve.length if s["length2D"] < 5.0*s["accuracy_radius"]: del_strokes.append(s_idx) old_indices.append(s["old_index"]) elif len(strokes_array[s_idx]) < 2 or s["accuracy_radius"] is None: del_strokes.append(s_idx) old_indices.append(s["old_index"]) for i in sorted(del_strokes, reverse=True): del strokes_topology[i] del_intersections = [] for i in sorted(old_indices, reverse=True): for inter_idx, inter in enumerate(intersections): if inter["strokes_indices"][0] - 1 == i or \ inter["strokes_indices"][1] - 1 == i: del_intersections.append(inter_idx) del_intersections = np.unique(del_intersections) for i in sorted(del_intersections, reverse=True): del intersections[i]
def computeMaxError(points, bez, parameters): maxDist = 0.0 splitPoint = len(points) / 2 for i, (point, u) in enumerate(zip(points, parameters)): dist = linalg.norm(bezier.q(bez, u) - point)**2 if dist > maxDist: maxDist = dist splitPoint = i return maxDist, splitPoint
def computeMaxError(points, bez, parameters): maxDist = 0.0 splitPoint = len(points)/2 for i, (point, u) in enumerate(zip(points, parameters)): dist = linalg.norm(bezier.q(bez, u)-point)**2 if dist > maxDist: maxDist = dist splitPoint = i return maxDist, splitPoint
def generateBezier(points, parameters, leftTangent, rightTangent): bezCurve = [points[0], None, None, points[-1]] # compute the A's A = zeros((len(parameters), 2, 2)) for i, u in enumerate(parameters): A[i][0] = leftTangent * 3 * (1 - u)**2 * u A[i][1] = rightTangent * 3 * (1 - u) * u**2 # Create the C and X matrices C = zeros((2, 2)) X = zeros(2) for i, (point, u) in enumerate(zip(points, parameters)): C[0][0] += dot(A[i][0], A[i][0]) C[0][1] += dot(A[i][0], A[i][1]) C[1][0] += dot(A[i][0], A[i][1]) C[1][1] += dot(A[i][1], A[i][1]) tmp = point - bezier.q([points[0], points[0], points[-1], points[-1]], u) X[0] += dot(A[i][0], tmp) X[1] += dot(A[i][1], tmp) # Compute the determinants of C and X det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1] det_C0_X = C[0][0] * X[1] - C[1][0] * X[0] det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1] # Finally, derive alpha values alpha_l = 0.0 if det_C0_C1 == 0 else det_X_C1 / det_C0_C1 alpha_r = 0.0 if det_C0_C1 == 0 else det_C0_X / det_C0_C1 # If alpha negative, use the Wu/Barsky heuristic (see text) */ # (if alpha is 0, you get coincident control points that lead to # divide by zero in any subsequent NewtonRaphsonRootFind() call. */ segLength = linalg.norm(points[0] - points[-1]) epsilon = 1.0e-6 * segLength if alpha_l < epsilon or alpha_r < epsilon: # fall back on standard (probably inaccurate) formula, and subdivide further if needed. bezCurve[1] = bezCurve[0] + leftTangent * (segLength / 3.0) bezCurve[2] = bezCurve[3] + rightTangent * (segLength / 3.0) else: # First and last control points of the Bezier curve are # positioned exactly at the first and last data points # Control points 1 and 2 are positioned an alpha distance out # on the tangent vectors, left and right, respectively bezCurve[1] = bezCurve[0] + leftTangent * alpha_l bezCurve[2] = bezCurve[3] + rightTangent * alpha_r return bezCurve
def generateBezier(points, parameters, leftTangent, rightTangent): bezCurve = [points[0], None, None, points[-1]] # compute the A's A = zeros((len(parameters), 2, 2)) for i, u in enumerate(parameters): A[i][0] = leftTangent * 3*(1-u)**2 * u A[i][1] = rightTangent * 3*(1-u) * u**2 # Create the C and X matrices C = zeros((2, 2)) X = zeros(2) for i, (point, u) in enumerate(zip(points, parameters)): C[0][0] += dot(A[i][0], A[i][0]) C[0][1] += dot(A[i][0], A[i][1]) C[1][0] += dot(A[i][0], A[i][1]) C[1][1] += dot(A[i][1], A[i][1]) tmp = point - bezier.q([points[0], points[0], points[-1], points[-1]], u) X[0] += dot(A[i][0], tmp) X[1] += dot(A[i][1], tmp) # Compute the determinants of C and X det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1] det_C0_X = C[0][0] * X[1] - C[1][0] * X[0] det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1] # Finally, derive alpha values alpha_l = 0.0 if det_C0_C1 == 0 else det_X_C1 / det_C0_C1 alpha_r = 0.0 if det_C0_C1 == 0 else det_C0_X / det_C0_C1 # If alpha negative, use the Wu/Barsky heuristic (see text) */ # (if alpha is 0, you get coincident control points that lead to # divide by zero in any subsequent NewtonRaphsonRootFind() call. */ segLength = linalg.norm(points[0] - points[-1]) epsilon = 1.0e-6 * segLength if alpha_l < epsilon or alpha_r < epsilon: # fall back on standard (probably inaccurate) formula, and subdivide further if needed. bezCurve[1] = bezCurve[0] + leftTangent * (segLength / 3.0) bezCurve[2] = bezCurve[3] + rightTangent * (segLength / 3.0) else: # First and last control points of the Bezier curve are # positioned exactly at the first and last data points # Control points 1 and 2 are positioned an alpha distance out # on the tangent vectors, left and right, respectively bezCurve[1] = bezCurve[0] + leftTangent * alpha_l bezCurve[2] = bezCurve[3] + rightTangent * alpha_r return bezCurve
def newtonRaphsonRootFind(bez, point, u): """ Newton's root finding algorithm calculates f(x)=0 by reiterating x_n+1 = x_n - f(x_n)/f'(x_n) We are trying to find curve parameter u for some point p that minimizes the distance from that point to the curve. Distance point to curve is d=q(u)-p. At minimum distance the point is perpendicular to the curve. We are solving f = q(u)-p * q'(u) = 0 with f' = q'(u) * q'(u) + q(u)-p * q''(u) gives u_n+1 = u_n - |q(u_n)-p * q'(u_n)| / |q'(u_n)**2 + q(u_n)-p * q''(u_n)| """ d = bezier.q(bez, u)-point numerator = (d * bezier.qprime(bez, u)).sum() denominator = (bezier.qprime(bez, u)**2 + d * bezier.qprimeprime(bez, u)).sum() if denominator == 0.0: return u else: return u - numerator/denominator
def create_bezier(b): points = [bezier.q(b, t / 50.0).tolist() for t in range(0, 51)] return np.array(points)