Exemple #1
0
static void
poly_level_do_with_mask(GwyDataField *dfield,
                        GwyDataField *mask,
                        GwyDataField *result,
                        GwyDataField *bg,
                        const PolyLevelArgs *args)
{
    gint *term_powers;
    gdouble *coeffs;
    gint nterms, i, j, k;

    k = 0;
    if (args->independent) {
        nterms = (args->col_degree + 1)*(args->row_degree + 1);
        term_powers = g_new(gint, 2*nterms);
        for (i = 0; i <= args->col_degree; i++) {
            for (j = 0; j <= args->row_degree; j++) {
                term_powers[k++] = i;
                term_powers[k++] = j;
            }
        }
    }
    else {
        nterms = (args->max_degree + 1)*(args->max_degree + 2)/2;
        term_powers = g_new(gint, 2*nterms);
        for (i = 0; i <= args->max_degree; i++) {
            for (j = 0; j <= args->max_degree - i; j++) {
                term_powers[k++] = i;
                term_powers[k++] = j;
            }
        }
    }

    coeffs = gwy_data_field_fit_poly(dfield, mask, nterms, term_powers,
                                     args->masking == GWY_MASK_EXCLUDE, NULL);
    gwy_data_field_subtract_poly(result, nterms, term_powers, coeffs);
    gwy_data_field_data_changed(result);

    if (bg) {
        for (i = 0; i < nterms; i++) {
            coeffs[i] = -coeffs[i];
        }
        gwy_data_field_subtract_poly(bg, nterms, term_powers, coeffs);
        gwy_data_field_data_changed(bg);
    }

    g_free(coeffs);
    g_free(term_powers);
}
Exemple #2
0
/* Does not include x and y offsets of the data field */
static gboolean
curvature_calculate(GwyDataField *dfield,
                    GwyDataField *mask,
                    const CurvatureArgs *args,
                    gdouble *params,
                    Intersection *i1,
                    Intersection *i2)
{
    enum { DEGREE = 2 };
    enum { A, BX, CXX, BY, CXY, CYY, NTERMS };
    gint term_powers[2*NTERMS];
    gdouble coeffs[NTERMS], ccoeffs[NTERMS];
    gdouble xreal, yreal, qx, qy, q, mx, my;
    gint xres, yres, i, j, k;
    gboolean ok;

    k = 0;
    g_assert(NTERMS == (DEGREE + 1)*(DEGREE + 2)/2);
    for (i = 0; i <= DEGREE; i++) {
        for (j = 0; j <= DEGREE - i; j++) {
            term_powers[k++] = j;
            term_powers[k++] = i;
        }
    }

    gwy_data_field_fit_poly(dfield, mask, NTERMS, term_powers,
                            args->masking != GWY_MASK_INCLUDE, coeffs);
    gwy_debug("NORM a=%g, bx=%g, by=%g, cxx=%g, cxy=%g, cyy=%g",
              coeffs[A], coeffs[BX], coeffs[BY],
              coeffs[CXX], coeffs[CXY], coeffs[CYY]);

    /* Transform coeffs from normalized coordinates to coordinates that are
     * still numerically around 1 but have the right aspect ratio. */
    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    xreal = gwy_data_field_get_xreal(dfield);
    yreal = gwy_data_field_get_yreal(dfield);
    qx = 2.0/xreal*xres/(xres - 1.0);
    qy = 2.0/yreal*yres/(yres - 1.0);
    q = sqrt(qx*qy);
    mx = sqrt(qx/qy);
    my = sqrt(qy/qx);

    ccoeffs[0] = coeffs[A];
    ccoeffs[1] = mx*coeffs[BX];
    ccoeffs[2] = my*coeffs[BY];
    ccoeffs[3] = mx*mx*coeffs[CXX];
    ccoeffs[4] = coeffs[CXY];
    ccoeffs[5] = my*my*coeffs[CYY];
    gwy_math_curvature(ccoeffs,
                       params + PARAM_R1, params + PARAM_R2,
                       params + PARAM_PHI1, params + PARAM_PHI2,
                       params + PARAM_X0, params + PARAM_Y0, params + PARAM_A);
    /* Transform to physical values. */
    /* FIXME: Why we have q*q here? */
    params[PARAM_R1] = 1.0/(q*q*params[PARAM_R1]);
    params[PARAM_R2] = 1.0/(q*q*params[PARAM_R2]);
    params[PARAM_X0] = params[PARAM_X0]/q + 0.5*xreal;
    params[PARAM_Y0] = params[PARAM_Y0]/q + 0.5*yreal;

    ok = TRUE;
    for (i = 0; i < 2; i++) {
        ok &= intersect_with_boundary(params[PARAM_X0], params[PARAM_Y0],
                                      -params[PARAM_PHI1 + i],
                                      xreal, yreal, i1 + i, i2 + i);
    }

    return ok;
}