예제 #1
0
static void
_cpml_sanity_put_intersections(gint i)
{
    CpmlSegment segment;
    CpmlPrimitive primitive1, primitive2;
    CpmlPair pair;

    /* Set primitive1 to 1.1 and primitive 2 to 2.2,
     * so there is an intersection point in (1, 1) */
    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&primitive1, &segment);

    cpml_segment_next(&segment);
    cpml_primitive_from_segment(&primitive2, &segment);
    cpml_primitive_next(&primitive2);

    switch (i) {
    case 1:
        cpml_primitive_put_intersections(NULL, &primitive2, 2, &pair);
        break;
    case 2:
        cpml_primitive_put_intersections(&primitive1, NULL, 2, &pair);
        break;
    case 3:
        cpml_primitive_put_intersections(&primitive1, &primitive2, 2, NULL);
        break;
    default:
        g_test_trap_assert_failed();
        break;
    }
}
예제 #2
0
파일: adg-path.c 프로젝트: bert/adg
static void
_adg_do_fillet(AdgPath *path, CpmlPrimitive *current)
{
    AdgPathPrivate *data;
    CpmlPrimitive *last, *current_dup, *last_dup;
    gdouble radius, offset, pos;
    CpmlPair center, vector, p[3];

    data = path->data;
    last = &data->last;
    current_dup = cpml_primitive_deep_dup(current);
    last_dup = cpml_primitive_deep_dup(last);
    radius = data->operation.data.fillet.radius;
    offset = _adg_is_convex(last_dup, current_dup) ? -radius : radius;

    /* Find the center of the fillet from the intersection between
     * the last and current primitives offseted by radius */
    cpml_primitive_offset(current_dup, offset);
    cpml_primitive_offset(last_dup, offset);
    if (cpml_primitive_put_intersections(current_dup, last_dup, 1, &center) == 0) {
        g_warning(_("%s: fillet with radius of %lf is not applicable here"),
                  G_STRLOC, radius);
        g_free(current_dup);
        g_free(last_dup);
        return;
    }

    /* Compute the start point of the fillet */
    pos = cpml_primitive_get_closest_pos(last_dup, &center);
    cpml_primitive_put_vector_at(last_dup, pos, &vector);
    cpml_vector_set_length(&vector, offset);
    cpml_vector_normal(&vector);
    p[0].x = center.x - vector.x;
    p[0].y = center.y - vector.y;

    /* Compute the mid point of the fillet */
    cpml_pair_from_cairo(&vector, current->org);
    vector.x -= center.x;
    vector.y -= center.y;
    cpml_vector_set_length(&vector, radius);
    p[1].x = center.x + vector.x;
    p[1].y = center.y + vector.y;

    /* Compute the end point of the fillet */
    pos = cpml_primitive_get_closest_pos(current_dup, &center);
    cpml_primitive_put_vector_at(current_dup, pos, &vector);
    cpml_vector_set_length(&vector, offset);
    cpml_vector_normal(&vector);
    p[2].x = center.x - vector.x;
    p[2].y = center.y - vector.y;

    g_free(current_dup);
    g_free(last_dup);

    /* Change the end point of the last primitive */
    cpml_primitive_set_point(last, -1, &p[0]);

    /* Change the start point of the current primitive */
    cpml_primitive_set_point(current, 0, &p[2]);

    /* Add the fillet arc */
    data->operation.action = ADG_ACTION_NONE;
    adg_path_append(path, CPML_ARC, &p[1], &p[2]);
}