/** * Checks that the 3 given points makes a valid triangle. Returns 0 when the * triangle contains duplicate points or the 3 points make a straight line. * @param point1 * @param point2 * @param point3 * @return */ int is_illegal_triangle(Point point1, Point point2, Point point3){ //Overlapping points are illegal if(has_overlapping_points(point1, point2, point3)){ return 1; } /* rise/run */ Slope slope_1_2 = calculate_slope(point1, point2); Slope slope_1_3 = calculate_slope(point1, point3); //Equal slopes means all 3 points form one straight line. int result = are_slopes_equal(slope_1_2, slope_1_3); return result; }
int Get_curvature_array(double* resolution, double* x, double* y, double* xcurv, double* ycurv, int number_of_locations) { int row, col; int i, status; if ( gis_grid.slope == 0 ) { status = calculate_slope(); if ( status != 0 ) return status; } if ( gis_grid.xcurv == 0 ) { status = calculate_curvature(); if ( status != 0 ) return status; } for ( i = 0; i < number_of_locations; i++ ) { if ( x[i] >= gis_grid.ghead.xmin && x[i] <= gis_grid.ghead.xmax && y[i] >= gis_grid.ghead.ymin && y[i] <= gis_grid.ghead.ymax ) { row = (int)(( gis_grid.ghead.ymax - y[i] ) / gis_grid.ghead.resolution); col = (int)(( x[i] - gis_grid.ghead.xmin ) / gis_grid.ghead.resolution); xcurv[i] = gis_grid.xcurv[row][col]; ycurv[i] = gis_grid.ycurv[row][col]; } } return 0; }
int calculate_curvature() { int row, col; int status; if ( gis_grid.xslope == 0 ) { status = calculate_slope(); if ( status != 0 ) return status; } free_float_matrix ( gis_grid.xcurv ); free_float_matrix ( gis_grid.ycurv ); if ( ! ( gis_grid.xcurv = alloc_float_matrix ( gis_grid.ghead.nrows, gis_grid.ghead.ncols ) ) ) return -3; /*memory error*/ if ( ! ( gis_grid.ycurv = alloc_float_matrix ( gis_grid.ghead.nrows, gis_grid.ghead.ncols ) ) ) return -3; /*memory error*/ for (row = 1; row < gis_grid.ghead.nrows - 1; row++) { for (col = 1; col < gis_grid.ghead.ncols - 1; col++) { gis_grid.xcurv[row][col] = ( ( gis_grid.slope[row-1][col+1] - gis_grid.slope[row-1][col-1] ) + 2 * ( gis_grid.slope[row ][col+1] - gis_grid.slope[row ][col-1] ) + ( gis_grid.slope[row+1][col+1] - gis_grid.slope[row+1][col-1] ) ) / ( 8 * (float)gis_grid.ghead.resolution ); gis_grid.ycurv[row][col] = ( ( gis_grid.slope[row-1][col-1] - gis_grid.slope[row+1][col-1] ) + 2 * ( gis_grid.slope[row-1][col ] - gis_grid.slope[row+1][col ] ) + ( gis_grid.slope[row-1][col+1] - gis_grid.slope[row+1][col+1] ) ) / ( 8 * (float)gis_grid.ghead.resolution ); } } for (col = 1; col < gis_grid.ghead.ncols - 1; col++) { gis_grid.xcurv[0][col] = gis_grid.xcurv[1][col]; gis_grid.xcurv[gis_grid.ghead.nrows-1][col] = gis_grid.xcurv[gis_grid.ghead.nrows-2][col]; gis_grid.ycurv[0][col] = gis_grid.ycurv[1][col]; gis_grid.ycurv[gis_grid.ghead.nrows-1][col] = gis_grid.ycurv[gis_grid.ghead.nrows-2][col]; } for (row = 0; row < gis_grid.ghead.nrows; row++) { gis_grid.xcurv[row][0] = gis_grid.xcurv[row][1]; gis_grid.xcurv[row][gis_grid.ghead.ncols-1] = gis_grid.xcurv[row][gis_grid.ghead.ncols-2]; gis_grid.ycurv[row][0] = gis_grid.ycurv[row][1]; gis_grid.ycurv[row][gis_grid.ghead.ncols-1] = gis_grid.ycurv[row][gis_grid.ghead.ncols-2]; } return 0; }
int Get_slope_grid(double resolution, double xmin, double xmax, double ymin, double ymax, double* slope) { int status; if ( gis_grid.slope == 0 ) { status = calculate_slope(); if ( status != 0 ) return status; } get_grid( resolution, xmin, xmax, ymin, ymax, gis_grid.slope, slope); return 0; }
int Get_curvature_grid(double resolution, double xmin, double xmax, double ymin, double ymax, double* xcurv, double* ycurv) { int status; if ( gis_grid.slope == 0 ) { status = calculate_slope(); if ( status != 0 ) return status; } if ( gis_grid.xcurv == 0 ) { status = calculate_curvature(); if ( status != 0 ) return status; } get_grid( resolution, xmin, xmax, ymin, ymax, gis_grid.xcurv, xcurv); get_grid( resolution, xmin, xmax, ymin, ymax, gis_grid.ycurv, ycurv); return 0; }
int Get_slope(double resolution, double x, double y, double* xslope, double* yslope) { int status; if ( gis_grid.xslope == 0 ) { status = calculate_slope(); if ( status != 0 ) return status; } if ( x >= gis_grid.ghead.xmin && x <= gis_grid.ghead.xmax && y >= gis_grid.ghead.ymin && y <= gis_grid.ghead.ymax ) { // row = ( gis_grid.ghead.ymax - y ) / gis_grid.ghead.resolution; // col = ( x - gis_grid.ghead.xmin ) / gis_grid.ghead.resolution; // *xslope = gis_grid.xslope[row][col]; // *yslope = gis_grid.yslope[row][col]; x = ( x - gis_grid.ghead.xmin ) / gis_grid.ghead.resolution; y = ( gis_grid.ghead.ymax - y ) / gis_grid.ghead.resolution; if ( (int)y >= gis_grid.ghead.nrows-1 || (int)x >= gis_grid.ghead.ncols-1 ) { if((int)y >= gis_grid.ghead.nrows-1) y=gis_grid.ghead.nrows-1; if((int)x >= gis_grid.ghead.ncols-1) x=gis_grid.ghead.ncols-1; *xslope = gis_grid.xslope[(int)y-1][(int)x-1]; *yslope = gis_grid.yslope[(int)y-1][(int)x-1]; } else { *xslope = interpolate_bilinear_at ( gis_grid.ghead.resolution, x, y, gis_grid.xslope ); *yslope = interpolate_bilinear_at ( gis_grid.ghead.resolution, x, y, gis_grid.yslope ); } } return 0; }
int Get_curvature(double resolution, double x, double y, double* xcurv, double* ycurv) { int row, col, i, j; int status; float** xxcurv; float** yycurv; double x1, y1; xxcurv = alloc_float_matrix(2,2); yycurv = alloc_float_matrix(2,2); if ( !xxcurv || !yycurv) return -3; if ( gis_grid.xslope == 0 ) { status = calculate_slope(); if ( status != 0 ) return status; } if ( x >= gis_grid.ghead.xmin && x <= gis_grid.ghead.xmax && y >= gis_grid.ghead.ymin && y <= gis_grid.ghead.ymax ) { row = (int)(( gis_grid.ghead.ymax - y ) / gis_grid.ghead.resolution); if ( row == 0 ) row++; if ( row == gis_grid.ghead.nrows - 1 ) row--; col = (int)(( x - gis_grid.ghead.xmin ) / gis_grid.ghead.resolution); if ( col == 0 ) col++; if ( col == gis_grid.ghead.ncols - 1 ) col--; if ( col >= (gis_grid.ghead.ncols - 3) || row >= gis_grid.ghead.nrows - 3 ) { *xcurv = ( ( gis_grid.xslope[row-1][col+1] - gis_grid.xslope[row-1][col-1] ) + 2 * ( gis_grid.xslope[row ][col+1] - gis_grid.xslope[row ][col-1] ) + ( gis_grid.xslope[row+1][col+1] - gis_grid.xslope[row+1][col-1] ) ) / ( 8 * gis_grid.ghead.resolution ); *ycurv = ( ( gis_grid.yslope[row-1][col-1] - gis_grid.yslope[row+1][col-1] ) + 2 * ( gis_grid.yslope[row-1][col ] - gis_grid.yslope[row+1][col ] ) + ( gis_grid.yslope[row-1][col+1] - gis_grid.yslope[row+1][col+1] ) ) / ( 8 * gis_grid.ghead.resolution ); } else { for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { xxcurv[i][j] = ( ( gis_grid.xslope[row+i-1][col+j+1] - gis_grid.xslope[row+i-1][col+j-1] ) + 2 * ( gis_grid.xslope[row+i][col+j+1] - gis_grid.xslope[row+i][col+j-1] ) + ( gis_grid.xslope[row+i+1][col+j+1] - gis_grid.xslope[row+i+1][col+j-1] ) ) / ( 8 * (float)gis_grid.ghead.resolution ); yycurv[i][j] = ( ( gis_grid.yslope[row+i-1][col+j-1] - gis_grid.yslope[row+i+1][col+j-1] ) + 2 * ( gis_grid.yslope[row+i-1][col+j] - gis_grid.yslope[row+i+1][col+j] ) + ( gis_grid.yslope[row+i-1][col+j+1] - gis_grid.yslope[row+i+1][col+j+1] ) ) / ( 8 * (float)gis_grid.ghead.resolution ); } } x1 = x - gis_grid.ghead.xmin - gis_grid.ghead.resolution*(double)col; y1 = gis_grid.ghead.ymax - gis_grid.ghead.resolution*(double)row - y; x1 = x1/gis_grid.ghead.resolution; y1 = y1/gis_grid.ghead.resolution; *xcurv = interpolate_bilinear_at ( gis_grid.ghead.resolution, x1, y1, xxcurv ); *ycurv = interpolate_bilinear_at ( gis_grid.ghead.resolution, x1, y1, yycurv ); } } free_float_matrix (xxcurv); free_float_matrix (yycurv); return 0; }
void FloatAuto::adjust_tangents() // recalculates tangents if current mode // implies automatic adjustment of tangents { if(!autos) return; if(tangent_mode == SMOOTH) { // normally, one would use the slope of chord between the neighbours. // but this could cause the curve to overshot extremal automation nodes. // (e.g when setting a fade node at zero, the curve could go negative) // we can interpret the slope of chord as a weighted mean value, where // the length of the interval is used as weight; we just use other // weights: intervall length /and/ reciprocal of slope. So, if the // connection to one of the neighbours has very low slope this will // dominate the calculated tangent slope at this automation node. // if the slope goes beyond the zero line, e.g if left connection // has positive and right connection has negative slope, then // we force the calculated tangent to be horizontal. float s, dxl, dxr, sl, sr; calculate_slope((FloatAuto*) previous, this, sl, dxl); calculate_slope(this, (FloatAuto*) next, sr, dxr); if(0 < sgn(sl) * sgn(sr)) { float wl = fabs(dxl) * (fabs(1.0/sl) + 1); float wr = fabs(dxr) * (fabs(1.0/sr) + 1); s = weighted_mean(sl, sr, wl, wr); } else s = 0; // fixed hoizontal tangent control_in_value = s * control_in_position; control_out_value = s * control_out_position; } else if(tangent_mode == LINEAR) { float g, dx; if(previous) { calculate_slope(this, (FloatAuto*)previous, g, dx); control_in_value = g * dx / 3; } if(next) { calculate_slope(this, (FloatAuto*)next, g, dx); control_out_value = g * dx / 3; } } else if(tangent_mode == TFREE && control_in_position && control_out_position) { float gl = control_in_value / control_in_position; float gr = control_out_value / control_out_position; float wl = fabs(control_in_value); float wr = fabs(control_out_value); float g = weighted_mean(gl, gr, wl, wr); control_in_value = g * control_in_position; control_out_value = g * control_out_position; } }