/////////////////////////////////////////////////////////////////////
//                      --- 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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
    }
}
Exemple #6
0
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();
}
Exemple #7
0
	/*!
	\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;
	}
Exemple #8
0
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;
}