Blob Blame History Raw


#include "line.h"



void lineTranspose(Vertex *l, int cols) {
  int cnt = cols*LN_SEGS+1;
  for(int i = 0; i < cnt; ++i) {
    Vertex *v = &l[i];
    v->p = vtranspose(v->p);
    v->t = vtranspose(v->t);
  }
}


void lineGenH(Vertex *l, int cols, double y, double cellw, double cellh, double jitter, double depth) {
  if (cols <= 0) return;

  double kx = cellh < cellw ? cellh/cellw : 1.0;
  double ky = cellw < cellh ? cellw/cellh : 1.0;

  int cnt = cols*LN_SEGS+1;
  for(int i = 0; i < cnt; ++i)
    l[i] = (Vertex){ {i*cellw/LN_SEGS, y}, {}, 1 };

  if (jitter) for(int i = 1; i < cnt-1; ++i) {
    l[i].p.x += randTwo()*kx*jitter*cellw/2;
    l[i].p.y += randTwo()*ky*jitter*cellh;
    l[i].w   += randOne()*0.25;
  }

  for(int c = 0; c < cols; ++c) {
    double j = jitter ? randTwo()*(1-kx)/3 : 0;
    l[c*LN_SEGS+1].p.x += ( 0.3 - kx/6 + j)*cellw;
    l[c*LN_SEGS+2].p.x += ( 0.1 - kx/6 + j)*cellw;
    l[c*LN_SEGS+3].p.x += (-0.1 + kx/6 + j)*cellw;
    l[c*LN_SEGS+4].p.x += (-0.3 + kx/6 + j)*cellw;
    double d = randSign()*depth*ky*cellh;
    l[c*LN_SEGS+2].p.y += d;
    l[c*LN_SEGS+3].p.y += d;
  }

  Vec b = l[0].p, e = l[cnt-1].p;
  b.x -= 1/3.0; e.x += 1/3.0;
  for(int i = 0; i < cnt; ++i) {
    Vertex *v = &l[i];
    Vec p0 = i       ? (v-1)->p : b;
    Vec p1 = i+1<cnt ? (v+1)->p : e;
    v->t = vmul(vsub(p1, p0), v->w/2);
  }
}


void lineGenV(Vertex *l, int rows, double x, double cellw, double cellh, double jitter, double depth) {
  lineGenH(l, rows, x, cellh, cellw, jitter, depth);
  lineTranspose(l, rows);
}


void linePut(Vertex *l, int cells, int levels) {
  int cnt = cells*LN_SEGS;
  if (cnt > 0) {
    for(int i = 1; i <= cnt; ++i) {
      Vertex v0 = l[i-1];
      Vertex v1 = l[i];
      cubicto(
        v0.p.x, v0.p.y,
        v0.p.x + v0.t.x/3, v0.p.y + v0.t.y/3,
        v1.p.x - v1.t.x/3, v1.p.y - v1.t.y/3,
        v1.p.x, v1.p.y,
        levels );
    }
  } else {
    for(int i = -1; i >= cnt; --i) {
      Vertex v0 = l[i+1];
      Vertex v1 = l[i];
      cubicto(
        v0.p.x, v0.p.y,
        v0.p.x - v0.t.x/3, v0.p.y - v0.t.y/3,
        v1.p.x + v1.t.x/3, v1.p.y + v1.t.y/3,
        v1.p.x, v1.p.y,
        levels );
    }
  }
}


void lineDraw(Vertex *l, int cells, int levels) {
  if (!cells) return;
  moveTo(l->p.x, l->p.y);
  linePut(l, cells, levels);
  strokePath();
}