Exemple #1
0
static void
_cpml_method_put_vector_at(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlVector vector;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    /* Line */
    cpml_primitive_from_segment(&primitive, &segment);
    cpml_primitive_put_vector_at(&primitive, 0, &vector);
    adg_assert_isapprox(vector.x, 3);
    adg_assert_isapprox(vector.y, 0);
    cpml_primitive_put_vector_at(&primitive, 1, &vector);
    adg_assert_isapprox(vector.x, 3);
    adg_assert_isapprox(vector.y, 0);
    cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
    adg_assert_isapprox(vector.x, 3);
    adg_assert_isapprox(vector.y, 0);

    /* Arc */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_vector_at(&primitive, 0, &vector);
    adg_assert_isapprox(vector.x, -0.077);
    adg_assert_isapprox(vector.y, 0.997);
    cpml_primitive_put_vector_at(&primitive, 1, &vector);
    adg_assert_isapprox(vector.x, 0.844);
    adg_assert_isapprox(vector.y, 0.537);
    cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
    adg_assert_isapprox(vector.x, 0.447);
    adg_assert_isapprox(vector.y, 0.894);

    /* Close */
    cpml_primitive_next(&primitive);
    /* TODO: not yet implemented
     * cpml_primitive_put_vector_at(&primitive, 0, &vector);
     * adg_assert_isapprox(vector.x, 6);
     * adg_assert_isapprox(vector.y, 7);
     * cpml_primitive_put_vector_at(&primitive, 1, &vector);
     * adg_assert_isapprox(vector.x, -2);
     * adg_assert_isapprox(vector.y, 2);
     * cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
     * adg_assert_isapprox(vector.x, 1);
     * adg_assert_isapprox(vector.y, 1); */

    /* Close */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_vector_at(&primitive, 0, &vector);
    adg_assert_isapprox(vector.x, 2);
    adg_assert_isapprox(vector.y, -1);
    cpml_primitive_put_vector_at(&primitive, 1, &vector);
    adg_assert_isapprox(vector.x, 2);
    adg_assert_isapprox(vector.y, -1);
    cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
    adg_assert_isapprox(vector.x, 2);
    adg_assert_isapprox(vector.y, -1);
}
Exemple #2
0
static gboolean
_adg_is_convex(const CpmlPrimitive *primitive1, const CpmlPrimitive *primitive2)
{
    CpmlVector v1, v2;
    gdouble angle1, angle2;

    cpml_primitive_put_vector_at(primitive1, -1, &v1);
    cpml_primitive_put_vector_at(primitive2, 0, &v2);

    /* Probably there is a smarter way to get this without trygonometry */
    angle1 = cpml_vector_angle(&v1);
    angle2 = cpml_vector_angle(&v2);

    if (angle1 > angle2)
        angle1 -= G_PI*2;

    return angle2-angle1 > G_PI;
}
Exemple #3
0
/**
 * cpml_segment_put_vector_at:
 * @segment: a #CpmlSegment
 * @pos:     the position value
 * @vector:  the destination #CpmlVector
 *
 * Gets the steepness of the point lying on @segment at position
 * @pos. @pos is an homogeneous factor where 0 is the start point,
 * 1 the end point, 0.5 the mid point and so on.
 * The relation <constant>0 < @pos < 1</constant> should be satisfied,
 * although some cases accept value outside this range.
 *
 * <important>
 * <title>TODO</title>
 * <itemizedlist>
 * <listitem>The actual implementation returns only the start and end
 *           steepness, that is only when @pos is 0 or 1.</listitem>
 * </itemizedlist>
 * </important>
 *
 * Since: 1.0
 **/
void
cpml_segment_put_vector_at(const CpmlSegment *segment, double pos,
                           CpmlVector *vector)
{
    CpmlPrimitive primitive;

    cpml_primitive_from_segment(&primitive, (CpmlSegment *) segment);

    /* Handle the common cases: start and end points */
    if (pos == 0) {
        cpml_primitive_put_vector_at(&primitive, 0, vector);
        return;
    }

    if (pos == 1) {
        while (cpml_primitive_next(&primitive))
            ;
        cpml_primitive_put_vector_at(&primitive, 1, vector);
        return;
    }
}
Exemple #4
0
static void
_cpml_sanity_put_vector_at(gint i)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlVector vector;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&primitive, &segment);

    switch (i) {
    case 1:
        cpml_primitive_put_vector_at(NULL, 1, &vector);
        break;
    case 2:
        cpml_primitive_put_vector_at(&primitive, 1, NULL);
        break;
    default:
        g_test_trap_assert_failed();
        break;
    }
}
Exemple #5
0
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]);
}