Skip to content

Instantly share code, notes, and snippets.

@bit-hack
Last active May 22, 2018 18:24
Show Gist options
  • Select an option

  • Save bit-hack/5a62af7ea5df839186756893372e3467 to your computer and use it in GitHub Desktop.

Select an option

Save bit-hack/5a62af7ea5df839186756893372e3467 to your computer and use it in GitHub Desktop.
derive triangle interpolation edge functions
// triangle setup
//
struct tri_setup_t {
tri_setup_t(const std::array<float2, 3> & t)
: _t(t)
, _i(tri_calc(t))
{
}
// calculate scaled edge function
//
// - scale the normals so points on the edge would be 0.f distance
// and the prime vertex would be at 1.f
//
std::array<float2, 3>
static tri_calc(const std::array<float2, 3> &t) {
// find edges
const float2 e01 = t[1] - t[0]; // 01
const float2 e12 = t[2] - t[1]; // 12
const float2 e20 = t[0] - t[2]; // 20
// edge normals
float2 n01 = float2::cross(e01);
float2 n12 = float2::cross(e12);
float2 n20 = float2::cross(e20);
// distance between edge and opposite vertex
const float d01 = float2::dot(n01, t[2] - t[0]);
const float d12 = float2::dot(n12, t[0] - t[1]);
const float d20 = float2::dot(n20, t[1] - t[2]);
// normalize to get interpolants
n01 /= d01;
n12 /= d12;
n20 /= d20;
// return interpolants for each vertex
return std::array<float2, 3>{n12, n20, n01};
}
// evaluate edge functions as point 'p'
//
std::array<float, 3> eval(const float2 &p) const {
// vector to point on edge
const float2 d0 = p - _t[1];
const float2 d1 = p - _t[2];
const float2 d2 = p - _t[0];
// distance from edge
const float e0 = float2::dot(d0, _i[0]); // n12
const float e1 = float2::dot(d1, _i[1]); // n20
const float e2 = float2::dot(d2, _i[2]); // n01
// return
return std::array<float, 3>{e0, e1, e2};
}
const std::array<float2, 3> _t; // vertices
const std::array<float2, 3> _i; // edge functions
const std::array<float, 3> _d; // plane distance
};
void raster(SDL_Surface *surf, const std::array<float2, 3> &v, const tri_setup_t &setup) {
const std::array<float2, 3> &i = setup._i;
std::array<float, 3> jy = setup.eval(v, i, float2{0, 0});
uint32_t *p = (uint32_t *)surf->pixels;
for (uint32_t y = 0; y < uint32_t(surf->h); ++y) {
std::array<float, 3> jx = jy;
for (uint32_t x = 0; x < uint32_t(surf->w); ++x) {
p[x] = 0x101010;
if (jx[0] > 0.f && jx[1] > 0.f && jx[2] > 0.f) {
const int cr = 0xff & int(jx[0] * 255.f);
const int cg = 0xff & int(jx[1] * 255.f);
const int cb = 0xff & int(jx[2] * 255.f);
p[x] = (cr << 16) | (cg << 8) | cb;
}
jx[0] += i[0].x;
jx[1] += i[1].x;
jx[2] += i[2].x;
}
p += surf->pitch / 4;
jy[0] += i[0].y;
jy[1] += i[1].y;
jy[2] += i[2].y;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment