void add_curve_segment(float cx, float cy, float ax, float ay) // Add a curve segment to the shape. The curve segment is a // quadratic bezier, running from the previous anchor point to // the given new anchor point (ax, ay), with (cx, cy) acting // as the control point in between. { if (cx == ax && cy == ay) { // Early-out for degenerate straight segments. add_line_segment(ax, ay); } else { // Subdivide, and add line segments... curve(s_last_point.m_x, s_last_point.m_y, cx, cy, ax, ay); } }
static void curve(float p0x, float p0y, float p1x, float p1y, float p2x, float p2y) // Recursive routine to generate bezier curve within tolerance. { #ifndef NDEBUG static int recursion_count = 0; recursion_count++; if (recursion_count > 500) { assert(0); // probably a bug! } #endif // not NDEBUG // @@ use struct point in here? // Midpoint on line between two endpoints. float midx = (p0x + p2x) * 0.5f; float midy = (p0y + p2y) * 0.5f; // Midpoint on the curve. float qx = (midx + p1x) * 0.5f; float qy = (midy + p1y) * 0.5f; float dist = fabsf(midx - qx) + fabsf(midy - qy); if (dist < s_tolerance) { // Emit edge. add_line_segment(p2x, p2y); } else { // Error is too large; subdivide. curve(p0x, p0y, (p0x + p1x) * 0.5f, (p0y + p1y) * 0.5f, qx, qy); curve(qx, qy, (p1x + p2x) * 0.5f, (p1y + p2y) * 0.5f, p2x, p2y); } #ifndef NDEBUG recursion_count--; #endif // not NDEBUG }
int process_eraseline(Drawing d) { double x1, x2, y1, y2, t; if (stack_size(d->stack) < 5) { return throw_error("Impossivel realizar operação. Motivo: há menos elementos na pilha do que o necessário (stack underflow).\n", PROCESSOR_ERROR_ERASELINE); } // printf("[DEBUG] Showing stack before creating line.\n"); // process_show(d->stack); t = stack_pop(d->stack); y2 = stack_pop(d->stack); x2 = stack_pop(d->stack); y1 = stack_pop(d->stack); x1 = stack_pop(d->stack); if (t < 0) { return throw_error("Impossivel realizar operação. Motivo: ao criar uma borracha com segmento de reta, a grossura não pode ser negativa.\n", PROCESSOR_ERROR_ERASELINE); } return add_line_segment(d, x1, y1, x2, y2, -t) ? PROCESSOR_SUCCESS : PROCESSOR_ERROR_ERASELINE; }