⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bspline.cpp

📁 C++ src for simple b-spline curve algorithm
💻 CPP
字号:
/*********************************************************************

 Simple b-spline curve algorithm

 Copyright 1994 by Keith Vertanen (vertankd@cda.mrs.umn.edu)

 Released to the public domain (your mileage may vary)

**********************************************************************/

#include <graphics.h>
#include <stdlib.h>

struct point {
  double x;
  double y;
  double z;
};

int set_graph(void);
void compute_intervals(int *u, int n, int t);
double blend(int k, int t, int *u, double v);
void compute_point(int *u, int n, int t, double v, point *control,
		   point *output);

void bspline(int n, int t, point *control, point *output, int num_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;
  double increment,interval;
  point calcxyz;
  int output_index;

  u=new int[n+t+1];
  compute_intervals(u, n, t);

  increment=(double) (n-t+2)/(num_output-1);  // how much parameter goes up each time
  interval=0;

  for (output_index=0; output_index<num_output-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[num_output-1].x=control[n].x;   // put in the last point
  output[num_output-1].y=control[n].y;
  output[num_output-1].z=control[n].z;

  delete u;
}

void main()
{
  int *u;
  int n,t,i;
  n=7;          // number of control points = n+1
  t=4;           // degree of polynomial = t-1

  point *pts;          // allocate our control point array
  pts=new point[n+1];
/*
  randomize();
  for (i=0; i<=n; i++)  // assign the control points randomly
  {
      (pts[i].x)=random(100)+(i*600/n);
      (pts[i].y)=random(500);
      (pts[i].z)=random(500);
  }
*/
  pts[0].x=10;  pts[0].y=100;  pts[0].z=0;
  pts[1].x=200;  pts[1].y=100;  pts[1].z=0;
  pts[2].x=345;  pts[2].y=300;  pts[2].z=0;
  pts[3].x=400;  pts[3].y=250;  pts[3].z=0;
  pts[4].x=500;  pts[4].y=550;  pts[4].z=0;
  pts[5].x=550;  pts[5].y=150;  pts[5].z=0;
  pts[6].x=570;  pts[6].y=50;   pts[6].z=0;
  pts[7].x=600;  pts[7].y=100;  pts[7].z=0;

  int resolution = 100;  // how many points our in our output array
  point *out_pts;
  out_pts = new point[resolution];

  bspline(n, t, pts, out_pts, resolution);
  if (set_graph())
  {
    setcolor(69);
    for (i=0; i<=n; i++)
      circle(pts[i].x,pts[i].y,2); // put circles at control points
    circle(pts[0].x,pts[0].y,0);  // drop the pen down at first control point
    for (i=0; i<resolution; i++)
    {
      setcolor(i);   // have a little fun with the colors
      putpixel(out_pts[i].x,out_pts[i].y,WHITE);
    }
  }
}

double blend(int k, int t, int *u, double v)  // calculate the blending value
{
  double value;

  if (t==1)			// base case for the recursion
  {
    if ((u[k]<=v) && (v<u[k+1]))
      value=1;
    else
      value=0;
  }
  else
  {
    if ((u[k+t-1]==u[k]) && (u[k+t]==u[k+1]))  // check for divide by zero
      value = 0;
    else
    if (u[k+t-1]==u[k]) // if a term's denominator is zero,use just the other
      value = (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v);
    else
    if (u[k+t]==u[k+1])
      value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v);
    else
      value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v) +
	      (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v);
  }
  return value;
}

void compute_intervals(int *u, int n, int t)   // figure out the knots
{
  int j;

  for (j=0; j<=n+t; j++)
  {
    if (j<t)
      u[j]=0;
    else
    if ((t<=j) && (j<=n))
      u[j]=j-t+1;
    else
    if (j>n)
      u[j]=n-t+2;  // if n-t=-2 then we're screwed, everything goes to 0
  }
}

void compute_point(int *u, int n, int t, double v, point *control,
			point *output)
{
  int k;
  double temp;

  // initialize the variables that will hold our outputted point
  output->x=0;
  output->y=0;
  output->z=0;

  for (k=0; k<=n; k++)
  {
    temp = blend(k,t,u,v);  // same blend is used for each dimension coordinate
    output->x = output->x + (control[k]).x * temp;
    output->y = output->y + (control[k]).y * temp;
    output->z = output->z + (control[k]).z * temp;
  }
}


int set_graph(void)
  {
	int graphdriver = DETECT, graphmode, error_code;

	//Initialize graphics system; must be EGA or VGA
	initgraph(&graphdriver, &graphmode, "c:\\borlandc\\bgi");
	error_code = graphresult();
	if (error_code != grOk)
		return(-1);               // No graphics hardware found
	if ((graphdriver != EGA) && (graphdriver != VGA))
	{
		closegraph();
		return 0;
	}
	return(1);                   // Graphics OK, so return "true"
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -