static int dt_circle_get_points(dt_develop_t *dev, float x, float y, float radius, float **points, int *points_count) { float wd = dev->preview_pipe->iwidth; float ht = dev->preview_pipe->iheight; //how many points do we need ? float r = radius*MIN(wd,ht); int l = (int) (2.0*M_PI*r); //buffer allocations *points = malloc(2*(l+1)*sizeof(float)); *points_count = l+1; //now we set the points (*points)[0] = x*wd; (*points)[1] = y*ht; for (int i=1; i<l+1; i++) { float alpha = (i-1)*2.0*M_PI/(float) l; (*points)[i*2] = (*points)[0] + r*cosf(alpha); (*points)[i*2+1] = (*points)[1] + r*sinf(alpha); } //and we transform them with all distorted modules if (dt_dev_distort_transform(dev,*points,l+1)) return 1; //if we failed, then free all and return free(*points); *points = NULL; *points_count = 0; return 0; }
static int dt_ellipse_get_points(dt_develop_t *dev, float xx, float yy, float radius_a, float radius_b, float rotation, float **points, int *points_count) { const float wd = dev->preview_pipe->iwidth; const float ht = dev->preview_pipe->iheight; const float v1 = (rotation / 180.0f) * M_PI; const float v2 = (rotation - 90.0f) / 180.0f * M_PI; float a, b, v; if(radius_a >= radius_b) { a = radius_a * MIN(wd, ht); b = radius_b * MIN(wd, ht); v = v1; } else { a = radius_b * MIN(wd, ht); b = radius_a * MIN(wd, ht); v = v2; } const float sinv = sinf(v); const float cosv = cosf(v); // how many points do we need? we only take every nth point and rely on interpolation (only affecting GUI // anyhow) const int n = 10; const float lambda = (a - b) / (a + b); const int l = MAX( 100, (int)((M_PI * (a + b) * (1.0f + (3.0f * lambda * lambda) / (10.0f + sqrtf(4.0f - 3.0f * lambda * lambda)))) / n)); // buffer allocations *points = calloc(2 * (l + 5), sizeof(float)); *points_count = l + 5; // now we set the points const float x = (*points)[0] = xx * wd; const float y = (*points)[1] = yy * ht; (*points)[2] = x + a * cos(v); (*points)[3] = y + a * sin(v); (*points)[4] = x - a * cos(v); (*points)[5] = y - a * sin(v); (*points)[6] = x + b * cos(v - M_PI / 2.0f); (*points)[7] = y + b * sin(v - M_PI / 2.0f); (*points)[8] = x - b * cos(v - M_PI / 2.0f); (*points)[9] = y - b * sin(v - M_PI / 2.0f); for(int i = 5; i < l + 5; i++) { float alpha = (i - 5) * 2.0 * M_PI / (float)l; (*points)[i * 2] = x + a * cosf(alpha) * cosv - b * sinf(alpha) * sinv; (*points)[i * 2 + 1] = y + a * cosf(alpha) * sinv + b * sinf(alpha) * cosv; } // and we transform them with all distorted modules if(dt_dev_distort_transform(dev, *points, l + 5)) return 1; // if we failed, then free all and return free(*points); *points = NULL; *points_count = 0; return 0; }
static int dt_gradient_get_points(dt_develop_t *dev, float x, float y, float rotation, float **points, int *points_count) { *points = NULL; *points_count = 0; const float wd = dev->preview_pipe->iwidth; const float ht = dev->preview_pipe->iheight; const float distance = 0.1f*fminf(wd, ht); const float xmax = wd - 1.0f; const float ymax = ht - 1.0f; const float v = (-rotation/180.0f)*M_PI; const float cosv = cos(v); const float sinv = sin(v); const float offset = sinv * x*wd - cosv * y*ht; // find intercept points of straight line and image borders int intercept_count = 0; float intercept[4]; int l; float delta_x, delta_y; if(sinv == 0.0f) { float is = -offset/cosv; if(is >= 0.0f && is <= ymax) { intercept[0] = 0; intercept[1] = is; intercept[2] = xmax; intercept[3] = is; intercept_count = 2; } } else if(cosv == 0.0f) { float is = offset/sinv; if(is >= 0.0f && is <= xmax) { intercept[0] = is; intercept[1] = 0; intercept[2] = is; intercept[3] = ymax; intercept_count = 2; } } else { float is = -offset/cosv; if(is >= 0.0f && is <= ymax) { intercept[0] = 0; intercept[1] = is; intercept_count++; } is = (xmax*sinv - offset)/cosv; if(is >= 0.0f && is <= ymax) { intercept[intercept_count*2] = xmax; intercept[intercept_count*2+1] = is; intercept_count++; } is = offset/sinv; if(is >= 0.0f && is <= xmax && intercept_count < 2) { intercept[intercept_count*2] = is; intercept[intercept_count*2+1] = 0; intercept_count++; } is = (ymax*cosv + offset)/sinv; if(is >= 0.0f && is <= xmax && intercept_count < 2) { intercept[intercept_count*2] = is; intercept[intercept_count*2+1] = ymax; intercept_count++; } } //how many points do we need ? if(intercept_count != 2) { l = 0; delta_x = delta_y = 0.0f; } else { l = (int)ceilf(sqrt((intercept[2]-intercept[0])*(intercept[2]-intercept[0])+(intercept[3]-intercept[1])*(intercept[3]-intercept[1]))); delta_x = (intercept[2]-intercept[0] != 0.0f) ? (intercept[2] - intercept[0])/l : 0.0f; delta_y = (intercept[3]-intercept[1] != 0.0f) ? (intercept[3] - intercept[1])/l : 0.0f; } //buffer allocations *points = malloc(2*(l+3)*sizeof(float)); if(*points == NULL) return 0; *points_count = l+3; //we set the anchor point (*points)[0] = x*wd; (*points)[1] = y*ht; //we set the pivot points const float v1 = (-(rotation-90.0f)/180.0f)*M_PI; const float x1 = x*wd + distance * cos(v1); const float y1 = y*ht + distance * sin(v1); (*points)[2] = x1; (*points)[3] = y1; const float v2 = (-(rotation+90.0f)/180.0f)*M_PI; const float x2 = x*wd + distance * cos(v2); const float y2 = y*ht + distance * sin(v2); (*points)[4] = x2; (*points)[5] = y2; //we set the line point float xx = intercept[0]; float yy = intercept[1]; for (int i=3; i<l+3; i++) { (*points)[i*2] = xx; (*points)[i*2+1] = yy; xx += delta_x; yy += delta_y; } //and we transform them with all distorted modules if (dt_dev_distort_transform(dev, *points, l+3)) return 1; //if we failed, then free all and return free(*points); *points = NULL; *points_count = 0; return 0; }