Blame onefile/curves.c

Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
#include <helianthus.h>
Ivan Mahonin 2ed0d1
#include <math.h>
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
#define COUNT     16
Ivan Mahonin 2ed0d1
#define SIZE      17
Ivan Mahonin 2ed0d1
#define RADIUS    5
Ivan Mahonin 2ed0d1
#define PRECISION 1e-5
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
double points[COUNT][2];
Ivan Mahonin 2ed0d1
double *curPoint;
Ivan Mahonin 2ed0d1
double curPointOffset[2];
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
int graphs[10];
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
double value(int ix)
Ivan Mahonin 2ed0d1
  { return points[ ((ix + COUNT/2)%COUNT + COUNT)%COUNT ][1]; }
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
double nearest(double x)
Ivan Mahonin 2ed0d1
  { return value(floor(x)); }
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
double linear(double x) {
Ivan Mahonin 2ed0d1
  x -= 0.5;
Ivan Mahonin 2ed0d1
  int ix = floor(x);
Ivan Mahonin 2ed0d1
  x -= ix;
Ivan Mahonin 2ed0d1
  return value(ix)*(1-x) + value(ix+1)*x;
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
double cubic(double x) {
Ivan Mahonin 2ed0d1
  x -= 0.5;
Ivan Mahonin 2ed0d1
  int ix = floor(x);
Ivan Mahonin 2ed0d1
  x -= ix;
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  double a = value(ix-1);
Ivan Mahonin 2ed0d1
  double b = value(ix+0);
Ivan Mahonin 2ed0d1
  double c = value(ix+1);
Ivan Mahonin 2ed0d1
  double d = value(ix+2);
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  return a*( -0.5*x*x*x +     x*x - 0.5*x )
Ivan Mahonin 2ed0d1
			 + b*(  1.5*x*x*x - 2.5*x*x + 1.0   )
Ivan Mahonin 2ed0d1
			 + c*( -1.5*x*x*x + 2.0*x*x + 0.5*x )
Ivan Mahonin 2ed0d1
			 + d*(  0.5*x*x*x - 0.5*x*x         );
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
double bspline(double x) {
Ivan Mahonin 2ed0d1
  x -= 0.5;
Ivan Mahonin 2ed0d1
  int ix = floor(x);
Ivan Mahonin 2ed0d1
  x -= ix;
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  double a = value(ix-1);
Ivan Mahonin 2ed0d1
  double b = value(ix+0);
Ivan Mahonin 2ed0d1
  double c = value(ix+1);
Ivan Mahonin 2ed0d1
  double d = value(ix+2);
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  return a*(  -x*x*x + 3*x*x - 3*x + 1)/6
Ivan Mahonin 2ed0d1
			 + b*( 3*x*x*x - 6*x*x + 4      )/6
Ivan Mahonin 2ed0d1
			 + c*(-3*x*x*x + 3*x*x + 3*x + 1)/6
Ivan Mahonin 2ed0d1
			 + d*(   x*x*x                  )/6;
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
void graph(double kx, double ky, double (*func)(double), unsigned int color) {
Ivan Mahonin 2ed0d1
  saveState();
Ivan Mahonin 2ed0d1
  strokeWidth(2);
Ivan Mahonin 2ed0d1
  stroke(color);
Ivan Mahonin 2ed0d1
  int hs = (int)ceil(SIZE*kx/2);
Ivan Mahonin 2ed0d1
  for(int x = -hs; x <= hs; ++x)
Ivan Mahonin 2ed0d1
    lineTo(x, func(x/kx)*ky);
Ivan Mahonin 2ed0d1
  strokePath();
Ivan Mahonin 2ed0d1
  restoreState();
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
void grid(double kx, double ky) {
Ivan Mahonin 2ed0d1
  saveState();
Ivan Mahonin 2ed0d1
  strokeWidth(1);
Ivan Mahonin 2ed0d1
  stroke(colorByRGBA(0, 0, 1, 0.125));
Ivan Mahonin 2ed0d1
  double hs = 0.5*SIZE;
Ivan Mahonin 2ed0d1
  for(int step = 16; step; step >>= 1) {
Ivan Mahonin 2ed0d1
    for(int i = 0; i <= SIZE/2; i += step) {
Ivan Mahonin 2ed0d1
      line(-hs*kx,  i*ky, hs*kx,  i*ky);
Ivan Mahonin 2ed0d1
      line(-hs*kx, -i*ky, hs*kx, -i*ky);
Ivan Mahonin 2ed0d1
      line( i*kx, -hs*ky,  i*kx, hs*ky);
Ivan Mahonin 2ed0d1
      line(-i*kx, -hs*ky, -i*kx, hs*ky);
Ivan Mahonin 2ed0d1
    }
Ivan Mahonin 2ed0d1
  }
Ivan Mahonin 2ed0d1
  restoreState();
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
void randomize() {
Ivan Mahonin 2ed0d1
  for(int i = 0; i < COUNT; ++i)
Ivan Mahonin 2ed0d1
    points[i][1] = randomFloat()*SIZE - SIZE/2.0;
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
void zero() {
Ivan Mahonin 2ed0d1
  for(int i = 0; i < COUNT; ++i)
Ivan Mahonin 2ed0d1
    points[i][1] = 0;
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
void init() {
Ivan Mahonin 2ed0d1
  for(int i = 0; i < COUNT; ++i)
Ivan Mahonin 2ed0d1
    points[i][0] = i - COUNT/2 + 0.5;
Ivan Mahonin 2ed0d1
  randomize();
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
void draw() {
Ivan Mahonin 2ed0d1
  double w = windowGetWidth();
Ivan Mahonin 2ed0d1
  double h = windowGetHeight();
Ivan Mahonin 2ed0d1
  double kx = w/SIZE;
Ivan Mahonin 2ed0d1
  double ky = h/SIZE;
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  saveState();
Ivan Mahonin 2ed0d1
  translate(w/2, h/2);
Ivan Mahonin 2ed0d1
  scale(1, -1);
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  if (keyWentDown("r")) { randomize(); curPoint = 0; }
Ivan Mahonin 2ed0d1
  if (keyWentDown("z")) { zero(); curPoint = 0; }
Ivan Mahonin 2ed0d1
  char key[] = "0";
Ivan Mahonin 2ed0d1
  for(int i = 0; i < 10; ++i, ++*key)
Ivan Mahonin 2ed0d1
    if (keyWentDown(key)) graphs[i] = !graphs[i];
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  int m = mouseWentDown("left");
Ivan Mahonin 2ed0d1
  double mx = mouseTransformedX();
Ivan Mahonin 2ed0d1
  double my = mouseTransformedY();
Ivan Mahonin 2ed0d1
  if (!mouseDown("left"))
Ivan Mahonin 2ed0d1
    { m = FALSE; curPoint = 0; }
Ivan Mahonin 2ed0d1
  if (curPoint) {
Ivan Mahonin 2ed0d1
    //curPoint[0] = (mx + curPointOffset[0])/kx;
Ivan Mahonin 2ed0d1
    curPoint[1] = (my + curPointOffset[1])/ky;
Ivan Mahonin 2ed0d1
  }
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  grid(kx, ky);
Ivan Mahonin 2ed0d1
  if (graphs[0]) graph(kx, ky, nearest, colorByRGBA(0, 0, 0, 0.5));
Ivan Mahonin 2ed0d1
  if (graphs[1]) graph(kx, ky, linear , colorByRGBA(0, 1, 0, 0.5));
Ivan Mahonin 2ed0d1
  if (graphs[2]) graph(kx, ky, cubic  , colorByRGBA(0, 0, 1, 0.5));
Ivan Mahonin 2ed0d1
  if (graphs[3]) graph(kx, ky, bspline, colorByRGBA(1, 0, 0, 0.5));
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  strokeWidth(2);
Ivan Mahonin 2ed0d1
  stroke(COLOR_BLUE);
Ivan Mahonin 2ed0d1
  fill(COLOR_WHITE);
Ivan Mahonin 2ed0d1
  for(int i = 0; i < COUNT; ++i) {
Ivan Mahonin 2ed0d1
    double x = points[i][0]*kx, y = points[i][1]*ky;
Ivan Mahonin 2ed0d1
    line(x, 0, x, y);
Ivan Mahonin 2ed0d1
    circle(x, y, RADIUS);
Ivan Mahonin 2ed0d1
    if (i == COUNT/2)
Ivan Mahonin 2ed0d1
      circle(x, y, RADIUS + 1);
Ivan Mahonin 2ed0d1
    double dx = x-mx, dy = y-my;
Ivan Mahonin 2ed0d1
    if (m && dx*dx + dy*dy <= RADIUS*RADIUS) {
Ivan Mahonin 2ed0d1
      curPoint = points[i];
Ivan Mahonin 2ed0d1
      curPointOffset[0] = dx;
Ivan Mahonin 2ed0d1
      curPointOffset[1] = dy;
Ivan Mahonin 2ed0d1
    }
Ivan Mahonin 2ed0d1
  }
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
  restoreState();
Ivan Mahonin 2ed0d1
}
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
Ivan Mahonin 2ed0d1
int main() {
Ivan Mahonin 2ed0d1
  windowSetVariableFrameRate();
Ivan Mahonin 2ed0d1
  windowSetResizable(TRUE);
Ivan Mahonin 2ed0d1
  windowSetInit(&init);
Ivan Mahonin 2ed0d1
  windowSetDraw(&draw);
Ivan Mahonin 2ed0d1
  windowRun();
Ivan Mahonin 2ed0d1
  return 0;
Ivan Mahonin 2ed0d1
}