Blame onefile/curves2.c

2ed0d1
2ed0d1
#include <helianthus.h></helianthus.h>
2ed0d1
2ed0d1
2ed0d1
#define COUNT     5
2ed0d1
#define RADIUS    5
2ed0d1
#define PRECISION 1e-5
2ed0d1
2ed0d1
2ed0d1
double points[COUNT][2];
2ed0d1
double *curPoint;
2ed0d1
double curPointOffset[2];
2ed0d1
2ed0d1
2ed0d1
2ed0d1
double calcCurveValue(double *curve, int count, double x) {
2ed0d1
  if (count <= 0) return 0;
2ed0d1
  if (count == 1) return curve[1];
2ed0d1
  if (x <= curve[0]) return curve[1];
2ed0d1
  if (x >= curve[(count-1)*2]) return curve[(count-1)*2 + 1];
2ed0d1
2ed0d1
  int i = 0;
2ed0d1
  while(i+1 < count && curve[(i+1)*2] < x)
2ed0d1
    ++i;
2ed0d1
2ed0d1
  double *p1 = &curve[i*2];
2ed0d1
  double *p0 = i   > 0     ? p1-2 : p1;
2ed0d1
  double *p2 = i+1 < count ? p1+2 : p1;
2ed0d1
  double *p3 = i+2 < count ? p2+2 : p2;
2ed0d1
2ed0d1
  double dx = p2[0] - p1[0];
2ed0d1
  if (dx <= PRECISION) return p1[1];
2ed0d1
2ed0d1
  double a = p1[1];
2ed0d1
  double b = p2[1];
2ed0d1
  double ta = p2[0]-p0[0]; ta = ta > PRECISION ? (p2[1]-p0[1])/ta*dx : 0;
2ed0d1
  double tb = p3[0]-p1[0]; tb = tb > PRECISION ? (p3[1]-p1[1])/tb*dx : 0;
2ed0d1
  double l = (x - p1[0])/dx;
2ed0d1
2ed0d1
  return a + (ta + (3*(b-a)-ta-ta-tb + (2*(a-b)+ta+tb)*l)*l)*l;
2ed0d1
}
2ed0d1
2ed0d1
2ed0d1
void init() {
2ed0d1
  for(int i = 0; i < COUNT; ++i)
2ed0d1
    points[i][0] = points[i][1] = i/(COUNT - 1.0);
2ed0d1
  calcCurveValue(points[0], COUNT, 0.3);
2ed0d1
}
2ed0d1
2ed0d1
2ed0d1
void draw() {
2ed0d1
  double w = windowGetWidth();
2ed0d1
  double h = windowGetHeight();
2ed0d1
2ed0d1
  saveState();
2ed0d1
  translate(0, h);
2ed0d1
  scale(1, -1);
2ed0d1
2ed0d1
  noFill();
2ed0d1
  stroke(colorByRGBA(0.75, 0.75, 0.75, 1));
2ed0d1
  strokeWidth(2);
2ed0d1
  rect(0, 0, w, h);
2ed0d1
2ed0d1
  strokeWidth(2);
2ed0d1
  line(0, 0, w, h);
2ed0d1
2ed0d1
  int m = mouseWentDown("left");
2ed0d1
  double mx = mouseTransformedX();
2ed0d1
  double my = mouseTransformedY();
2ed0d1
  if (!mouseDown("left"))
2ed0d1
    { m = FALSE; curPoint = 0; }
2ed0d1
  if (curPoint) {
2ed0d1
    curPoint[0] = (mx + curPointOffset[0])/w;
2ed0d1
    curPoint[1] = (my + curPointOffset[1])/h;
2ed0d1
  }
2ed0d1
2ed0d1
  stroke(COLOR_BLUE);
2ed0d1
  fill(COLOR_WHITE);
2ed0d1
  for(int i = 0; i < w+1; ++i)
2ed0d1
    lineTo(i, calcCurveValue(points[0], COUNT, i/w)*h);
2ed0d1
  strokePath();
2ed0d1
  for(int i = 0; i < COUNT; ++i) {
2ed0d1
    double x = points[i][0]*w, y = points[i][1]*h;
2ed0d1
    circle(x, y, RADIUS);
2ed0d1
    double dx = x-mx, dy = y-my;
2ed0d1
    if (m && dx*dx + dy*dy <= RADIUS*RADIUS) {
2ed0d1
      curPoint = points[i];
2ed0d1
      curPointOffset[0] = dx;
2ed0d1
      curPointOffset[1] = dy;
2ed0d1
    }
2ed0d1
  }
2ed0d1
2ed0d1
  restoreState();
2ed0d1
}
2ed0d1
2ed0d1
2ed0d1
int main() {
2ed0d1
  windowSetVariableFrameRate();
2ed0d1
  windowSetResizable(TRUE);
2ed0d1
  windowSetInit(&init);
2ed0d1
  windowSetDraw(&draw);
2ed0d1
  windowRun();
2ed0d1
  return 0;
2ed0d1
}