예제 #1
0
파일: adg-point.c 프로젝트: ntd/adg
/**
 * adg_point_get_pair:
 * @point: an #AdgPoint
 *
 * #AdgPoint is an evolution of the pair concept but internally the
 * relevant data is still stored in an #CpmlPair struct. This function
 * returns a copy of the internally owned pair.
 *
 * <note><para>
 * The #CpmlPair is the first field of an #AdgPoint struct so casting
 * is allowed between them and, in fact, it is often more convenient
 * than calling this function. Just remember to update the internal
 * pair by using adg_point_update() before.
 * </para></note>
 *
 * Returns: (transfer full): the pair of @point or <constant>NULL</constant> if the named pair does not exist.
 *
 * Since: 1.0
 **/
CpmlPair *
adg_point_get_pair(AdgPoint *point)
{
    g_return_val_if_fail(point != NULL, NULL);

    if (! adg_point_update(point))
        return NULL;

    return cpml_pair_dup(& point->pair);
}
예제 #2
0
static void
_adg_behavior_named_pair(void)
{
    CpmlPair p1 = { 123, 456 };
    AdgPoint *explicit_point, *explicit_point2, *model_point;
    AdgModel *model;
    CpmlPair *pair;

    explicit_point = adg_point_new();
    g_assert_nonnull(explicit_point);
    adg_point_set_pair(explicit_point, &p1);

    explicit_point2 = adg_point_new();
    g_assert_nonnull(explicit_point2);
    adg_point_set_pair_explicit(explicit_point2, p1.x, p1.y);

    /* Checking comparison APIs */
    g_assert_true(adg_point_equal(explicit_point, explicit_point2));
    adg_point_set_pair_explicit(explicit_point2, 78, 90);
    g_assert_false(adg_point_equal(explicit_point, explicit_point2));
    pair = (CpmlPair *) explicit_point2;
    adg_assert_isapprox(pair->x, 78);
    adg_assert_isapprox(pair->y, 90);

    pair = adg_point_get_pair(explicit_point);
    g_assert_true(cpml_pair_equal(pair, &p1));
    g_free(pair);

    model = ADG_MODEL(adg_path_new());
    g_assert_nonnull(model);
    adg_model_set_named_pair(model, "named-pair", &p1);

    model_point = adg_point_new();
    g_assert_nonnull(model_point);
    adg_point_set_pair_from_model(model_point, model, "named-pair");

    pair = adg_point_get_pair(model_point);
    g_assert_true(cpml_pair_equal(pair, &p1));
    g_free(pair);

    /* Ensure ADG does not consider an explicit point equals to
     * a point bound to a named pair with the same coordinates */
    g_assert_false(adg_point_equal(explicit_point, model_point));

    /* Check for lazy evaluation of named pairs */
    adg_point_set_pair_from_model(model_point, model, "unexistent-pair");
    pair = (CpmlPair *) model_point;
    adg_assert_isapprox(pair->x, p1.x);
    adg_assert_isapprox(pair->y, p1.y);

    /* Check behavior on undefined named pair */
    g_assert_false(adg_point_update(model_point));
    g_assert_null(adg_point_get_pair(model_point));

    adg_point_set_pair_from_model(model_point, model, "named-pair");
    g_assert_true(adg_point_update(model_point));

    /* Check for case sensitiveness */
    adg_point_set_pair_from_model(model_point, model, "Named-Pair");
    g_assert_null(adg_point_get_pair(model_point));
    g_assert_false(adg_point_update(model_point));

    /* Check if adg_point_get_pair() triggers an adg_point_update() */
    adg_point_set_pair_from_model(model_point, model, "named-pair");
    pair = adg_point_get_pair(model_point);
    g_assert_true(cpml_pair_equal(pair, &p1));
    g_free(pair);

    adg_point_destroy(explicit_point);
    adg_point_destroy(model_point);
    g_object_unref(model);
}
예제 #3
0
파일: adg-adim.c 프로젝트: bert/adg
static gboolean
_adg_get_info(AdgADim *adim, CpmlVector vector[],
              CpmlPair *center, gdouble *distance)
{
    AdgDim *dim;
    AdgADimPrivate *data;
    AdgPoint *ref1_point, *ref2_point, *pos_point;
    const CpmlPair *ref1, *ref2, *pos;
    const CpmlPair *org1, *org2;
    gdouble factor;

    dim = (AdgDim *) adim;
    data = adim->data;
    ref1_point = adg_dim_get_ref1(dim);
    ref2_point = adg_dim_get_ref2(dim);
    pos_point  = adg_dim_get_pos(dim);

    /* Check if the needed points are all properly defined */
    if (! adg_point_update(ref1_point) ||
        ! adg_point_update(ref2_point) ||
        ! adg_point_update(pos_point)  ||
        ! adg_point_update(data->org1) ||
        ! adg_point_update(data->org2))
    {
        return FALSE;
    }

    ref1 = (CpmlPair *) ref1_point;
    ref2 = (CpmlPair *) ref2_point;
    pos  = (CpmlPair *) pos_point;
    org1 = (CpmlPair *) data->org1;
    org2 = (CpmlPair *) data->org2;

    /* Check if the given points have valid coordinates */
    if (cpml_pair_equal(ref1, org1)) {
        g_warning(_("%s: ref1 and org1 cannot be coincidents (%lf, %lf)"),
                  G_STRLOC, ref1->x, ref1->y);
        return FALSE;
    }

    if (cpml_pair_equal(ref2, org2)) {
        g_warning(_("%s: ref2 and org2 cannot be coincidents (%lf, %lf)"),
                  G_STRLOC, ref2->x, ref2->y);
        return FALSE;
    }

    vector[0].x = ref1->x - org1->x;
    vector[0].y = ref1->y - org1->y;
    vector[2].x = ref2->x - org2->x;
    vector[2].y = ref2->y - org2->y;

    factor = vector[0].x * vector[2].y - vector[0].y * vector[2].x;
    if (factor == 0) {
        /* Parallel lines: hang with an error message */
        g_warning(_("%s: trying to set an angular dimension on parallel lines"),
                  G_STRLOC);
        return FALSE;
    }

    factor = ((ref1->y - ref2->y) * vector[2].x -
              (ref1->x - ref2->x) * vector[2].y) / factor;

    center->x = ref1->x + vector[0].x * factor;
    center->y = ref1->y + vector[0].y * factor;
    *distance = cpml_pair_distance(center, pos);
    data->angle1 = cpml_vector_angle(&vector[0]);
    data->angle2 = cpml_vector_angle(&vector[2]);
    while (data->angle2 < data->angle1)
        data->angle2 += G_PI * 2;

    cpml_vector_from_angle(&vector[1], (data->angle1 + data->angle2) / 2);

    return TRUE;
}