///////////////////////////////////////////////////////////////////// // --- B-Spline --- void BSpline::bspline(int ctrlPtsNum, int polyDegree, QVector3D *ctrlPts, QPointF *output, int num_output) { float *knotVector; double increment, interval; QPointF calcxyz; int output_index; knotVector = new float[ctrlPtsNum+polyDegree+1]; compute_intervals(knotVector, ctrlPtsNum, polyDegree); increment=(double) 1 / (num_output-1); // how much parameter goes up each time interval=0.0; std::string result2 = "test: "; char result[512] = {'\0'}; for(int i = 0; i<=ctrlPtsNum+polyDegree ;i++){ sprintf(result, "%f, ", knotVector[i]); result2.append(result); } for (output_index=0; output_index<num_output-1; output_index++) { compute_point(knotVector, ctrlPtsNum, polyDegree, interval, ctrlPts, &calcxyz); output[output_index].setX(calcxyz.x()); output[output_index].setY(calcxyz.y()); interval=interval+increment; // increment our parameter } output[num_output-1].setX(ctrlPts[ctrlPtsNum].x()); // put in the last point output[num_output-1].setY(ctrlPts[ctrlPtsNum].y()); delete knotVector; }
QPointF BSpline::getSplineAtPosY(int y, float precision, int maxIteration) { float interval = 0.25; float intPosition = 0.5; float *knotVector; QPointF calcxyz; knotVector = new float[numInternCtrlPts + polynomDegree + 1]; compute_intervals(knotVector, numInternCtrlPts, polynomDegree); while(true){ compute_point(knotVector, numInternCtrlPts, polynomDegree, intPosition, controlPts, &calcxyz); if(calcxyz.y() > y){ intPosition -= interval; }else{ intPosition += interval; } interval /= 2; if(fabs(calcxyz.y() - y) < precision) break; if(maxIteration <= 0){ break; } maxIteration--; } return calcxyz; }
QPointF *BSpline::calcIntervalArray() { if(!intervalArray){ QMessageBox::information(0, "splineAtPosX()", "BSpline::calcIntervalArray() pole neinicializovane!"); exit(EXIT_FAILURE); } if(iaUpToDate) return intervalArray; float *knotVector; double increment, interval; QPointF bsPoint; int outIndex; iaUpToDate = false; knotVector = new float[numInternCtrlPts + polynomDegree + 1]; compute_intervals(knotVector, numInternCtrlPts, polynomDegree); increment=(double) 1 / (iaLength - 1); // how much parameter goes up each time interval=0.0; for (outIndex = 0; outIndex < iaLength - 1; outIndex++) { compute_point(knotVector, numInternCtrlPts, polynomDegree, interval, controlPts, &bsPoint); intervalArray[outIndex].setX(bsPoint.x()); intervalArray[outIndex].setY(bsPoint.y()); interval=interval+increment; // increment our parameter } intervalArray[iaLength-1].setX(controlPts[numInternCtrlPts].x()); // put in the last point intervalArray[iaLength-1].setY(controlPts[numInternCtrlPts].y()); iaUpToDate = true; delete knotVector; return intervalArray; }
void splineShape::bspline(int n, int t, point *control, point *output) { /********************************************************************* Parameters: n - the number of control points minus 1 t - the degree of the polynomial plus 1 control - control point array made up of point stucture output - array in which the calculate spline points are to be put num_output - how many points on the spline are to be calculated Pre-conditions: n+2>t (no curve results if n+2<=t) control array contains the number of points specified by n output array is the proper size to hold num_output point structures **********************************************************************/ int *u; //puntero que almacena posteriormente en un vector los puntos double increment,interval; point calcxyz; //estructura punto, xyz int output_index; u=new int[n+t+1]; compute_intervals(u, n, t); increment=(double) (n-t+2)/(2*Ni-1); // how much parameter goes up each time interval=0; for (output_index=0; output_index<2*Ni-1; output_index++) { compute_point(u, n, t, interval, control, &calcxyz); output[output_index].x = calcxyz.x; output[output_index].y = calcxyz.y; output[output_index].z = calcxyz.z; interval=interval+increment; // increment our parameter } output[2*Ni-1].x=control[n].x; // put in the last point output[2*Ni-1].y=control[n].y; output[2*Ni-1].z=control[n].z; //ahora que tenemos los calculos hechos quiero generar un fichero de salida //para Gnuplot para poder ver los resultados. FILE *out; out = fopen("output/splinePoints.dat","w"); for (int i = 0; i < 2*Ni; i++) { fprintf(out, "%f\t%f\t%f\n", output[i].x,output[i].y,output[i].z); //printf("Coordenadas: %f\t%f\t%d\n", output[i].x,output[i].y,i,n); } fclose(out); delete u; }
static inline double interpolate_point_internal(const stp_curve_t *curve, double where) { int integer = where; double frac = where - (double) integer; double bhi, blo; if (frac == 0.0) { double val; if ((stp_sequence_get_point(curve->seq, integer, &val)) == 0) return HUGE_VAL; /* Infinity */ return val; } if (curve->recompute_interval) compute_intervals((stpi_cast_safe(curve))); if (curve->curve_type == STP_CURVE_TYPE_LINEAR) { double val; if ((stp_sequence_get_point(curve->seq, integer, &val)) == 0) return HUGE_VAL; /* Infinity */ return val + frac * curve->interval[integer]; } else { size_t point_count; double ival, ip1val; double retval; int i = integer; int ip1 = integer + 1; point_count = get_point_count(curve); if (ip1 >= point_count) ip1 -= point_count; if ((stp_sequence_get_point(curve->seq, i, &ival)) == 0 || (stp_sequence_get_point(curve->seq, ip1, &ip1val)) == 0) return HUGE_VAL; /* Infinity */ retval = do_interpolate_spline(ival, ip1val, frac, curve->interval[i], curve->interval[ip1], 1.0); stp_sequence_get_bounds(curve->seq, &blo, &bhi); if (retval > bhi) retval = bhi; if (retval < blo) retval = blo; return retval; } }
void CShaper::updatedata() { FillP2(); if(n>=degree) { float WantedX = 0.0; float dx = 1.f/(float)table_size; float y; KnoopVector *u; u = new KnoopVector[n+degree]; compute_intervals(u, n-1, degree); data[0] = 0.f; WantedX += dx; for(long i=1;i<table_size;i++) { y = GetBSplinePoint(WantedX,u); data[i] = y; WantedX += dx; } delete u; } else { float WantedX = 0.f; float dx = 1.f/(float)table_size; float y; data[0] = 0.f; WantedX += dx; for(long i=1;i<table_size;i++) { y = GetSplinePoint(WantedX); data[i] = y; WantedX += dx; } } data[table_size] = 2*data[table_size - 1] - data[table_size - 2]; //a and b float x1 = p2[n-2].x; float y1 = p2[n-2].y; float x2 = p2[n-1].x; float y2 = p2[n-1].y; float temp = x1 - x2; if(temp == 0.f) { if(y2 > y1) a = 1.f; else a = -1.f; } else a = (y1-y2)/temp; if(a > 2.f) a = 2.f; else if(a < -2.f) a = -2.f; b = y2; if(pPreview) pPreview->setDirty(); }
/*! \pre tv_plane and tu_plane must be set \post distances[2] is set with the distance closest_point_u, closest_point_v, edge_edge_dir are set too \return - 0: faces are paralele - 1: face U casts face V - 2: face V casts face U - 3: nearest edges */ SIMD_FORCE_INLINE GUINT cross_line_intersection_test() { // Compute direction of intersection line edge_edge_dir = tu_plane.cross(tv_plane); GREAL Dlen; VEC_LENGTH(edge_edge_dir,Dlen); if(Dlen<0.0001) { return 0; //faces near paralele } edge_edge_dir*= 1/Dlen;//normalize // Compute interval for triangle 1 GUINT tu_e0,tu_e1;//edge indices GREAL tu_scale_e0,tu_scale_e1;//edge scale if(!compute_intervals(du[0],du[1],du[2], du0du1,du0du2,tu_scale_e0,tu_scale_e1,tu_e0,tu_e1)) return 0; // Compute interval for triangle 2 GUINT tv_e0,tv_e1;//edge indices GREAL tv_scale_e0,tv_scale_e1;//edge scale if(!compute_intervals(dv[0],dv[1],dv[2], dv0dv1,dv0dv2,tv_scale_e0,tv_scale_e1,tv_e0,tv_e1)) return 0; //proyected vertices btVector3 up_e0 = tu_vertices[tu_e0].lerp(tu_vertices[(tu_e0+1)%3],tu_scale_e0); btVector3 up_e1 = tu_vertices[tu_e1].lerp(tu_vertices[(tu_e1+1)%3],tu_scale_e1); btVector3 vp_e0 = tv_vertices[tv_e0].lerp(tv_vertices[(tv_e0+1)%3],tv_scale_e0); btVector3 vp_e1 = tv_vertices[tv_e1].lerp(tv_vertices[(tv_e1+1)%3],tv_scale_e1); //proyected intervals GREAL isect_u[] = {up_e0.dot(edge_edge_dir),up_e1.dot(edge_edge_dir)}; GREAL isect_v[] = {vp_e0.dot(edge_edge_dir),vp_e1.dot(edge_edge_dir)}; sort_isect(isect_u[0],isect_u[1],tu_e0,tu_e1,up_e0,up_e1); sort_isect(isect_v[0],isect_v[1],tv_e0,tv_e1,vp_e0,vp_e1); const GREAL midpoint_u = 0.5f*(isect_u[0]+isect_u[1]); // midpoint const GREAL midpoint_v = 0.5f*(isect_v[0]+isect_v[1]); // midpoint if(midpoint_u<midpoint_v) { if(isect_u[1]>=isect_v[1]) // face U casts face V { return 1; } else if(isect_v[0]<=isect_u[0]) // face V casts face U { return 2; } // closest points closest_point_u = up_e1; closest_point_v = vp_e0; // calc edges and separation if(isect_u[1]+ MIN_EDGE_EDGE_DIS<isect_v[0]) //calc distance between two lines instead { SEGMENT_COLLISION( tu_vertices[tu_e1],tu_vertices[(tu_e1+1)%3], tv_vertices[tv_e0],tv_vertices[(tv_e0+1)%3], closest_point_u, closest_point_v); edge_edge_dir = closest_point_u-closest_point_v; VEC_LENGTH(edge_edge_dir,distances[2]); edge_edge_dir *= 1.0f/distances[2];// normalize } else { distances[2] = isect_v[0]-isect_u[1];//distance negative //edge_edge_dir *= -1.0f; //normal pointing from V to U } } else { if(isect_v[1]>=isect_u[1]) // face V casts face U { return 2; } else if(isect_u[0]<=isect_v[0]) // face U casts face V { return 1; } // closest points closest_point_u = up_e0; closest_point_v = vp_e1; // calc edges and separation if(isect_v[1]+MIN_EDGE_EDGE_DIS<isect_u[0]) //calc distance between two lines instead { SEGMENT_COLLISION( tu_vertices[tu_e0],tu_vertices[(tu_e0+1)%3], tv_vertices[tv_e1],tv_vertices[(tv_e1+1)%3], closest_point_u, closest_point_v); edge_edge_dir = closest_point_u-closest_point_v; VEC_LENGTH(edge_edge_dir,distances[2]); edge_edge_dir *= 1.0f/distances[2];// normalize } else { distances[2] = isect_u[0]-isect_v[1];//distance negative //edge_edge_dir *= -1.0f; //normal pointing from V to U } } return 3; }
int stp_curve_resample(stp_curve_t *curve, size_t points) { size_t limit = points; size_t old; size_t i; double *new_vec; CHECK_CURVE(curve); if (points == get_point_count(curve) && curve->seq && !(curve->piecewise)) return 1; if (points < 2) return 1; if (curve->wrap_mode == STP_CURVE_WRAP_AROUND) limit++; if (limit > curve_point_limit) return 0; old = get_real_point_count(curve); if (old) old--; if (!old) old = 1; new_vec = stp_malloc(sizeof(double) * limit); /* * Be very careful how we calculate the location along the scale! * If we're not careful how we do it, we might get a small roundoff * error */ if (curve->piecewise) { double blo, bhi; int curpos = 0; stp_sequence_get_bounds(curve->seq, &blo, &bhi); if (curve->recompute_interval) compute_intervals(curve); for (i = 0; i < old; i++) { double low; double high; double low_y; double high_y; double x_delta; if (!stp_sequence_get_point(curve->seq, i * 2, &low)) { stp_free(new_vec); return 0; } if (i == old - 1) high = 1.0; else if (!stp_sequence_get_point(curve->seq, ((i + 1) * 2), &high)) { stp_free(new_vec); return 0; } if (!stp_sequence_get_point(curve->seq, (i * 2) + 1, &low_y)) { stp_free(new_vec); return 0; } if (!stp_sequence_get_point(curve->seq, ((i + 1) * 2) + 1, &high_y)) { stp_free(new_vec); return 0; } stp_deprintf(STP_DBG_CURVE, "Filling slots at %ld %d: %f %f %f %f %ld\n", (long)i,curpos, high, low, high_y, low_y, (long)limit); x_delta = high - low; high *= (limit - 1); low *= (limit - 1); while (curpos <= high) { double frac = (curpos - low) / (high - low); if (curve->curve_type == STP_CURVE_TYPE_LINEAR) new_vec[curpos] = low_y + frac * (high_y - low_y); else new_vec[curpos] = do_interpolate_spline(low_y, high_y, frac, curve->interval[i], curve->interval[i + 1], x_delta); if (new_vec[curpos] < blo) new_vec[curpos] = blo; if (new_vec[curpos] > bhi) new_vec[curpos] = bhi; stp_deprintf(STP_DBG_CURVE, " Filling slot %d %f %f\n", curpos, frac, new_vec[curpos]); curpos++; } } curve->piecewise = 0; } else { for (i = 0; i < limit; i++) if (curve->gamma) new_vec[i] = interpolate_gamma_internal(curve, ((double) i * (double) old / (double) (limit - 1))); else new_vec[i] = interpolate_point_internal(curve, ((double) i * (double) old / (double) (limit - 1))); } stpi_curve_set_points(curve, points); stp_sequence_set_subrange(curve->seq, 0, limit, new_vec); curve->recompute_interval = 1; stp_free(new_vec); return 1; }