Skip to content

Instantly share code, notes, and snippets.

View nervoussystem's full-sized avatar

Jesse Louis-Rosenberg nervoussystem

View GitHub Profile
void meshOutlines(const vector<vector<array<float, 2> > > & crvs,vector<array<float, 2> > & outPts, vector<unsigned int> & indices) {
GEO::CDT2d cdt;
if (crvs.size() == 0) return;
//get bounding box
float minX = crvs[0][0][0], maxX = crvs[0][0][0], minY = crvs[0][0][1], maxY = crvs[0][0][1];
vector<double> pts;
for (int c = 0; c < crvs.size();++c) {
auto & crv = crvs[c];
float area = 0;
for (int i = 0; i < crv.size(); ++i) {
@nervoussystem
nervoussystem / volume.js
Last active April 22, 2016 14:20
Calculate the volume of a mesh stored in a VBO-like structure (vertex data in an array and triangle data in another array). Uses gl-matrix
var volume = 0;
var v1 = vec3.create(),
v2 = vec3.create(),
v3 = vec3.create();
var i,index1,index2,index3;
for(i=0;i<numIndices;) {
index1 = indices[i++]*3;
index2 = indices[i++]*3;
index3 = indices[i++]*3;
//pairing heap
//{elem:object, subheaps:[array of heaps]}
//subheaps might should be a linked list
function PairingHeap(obj) {
this.elem = obj;
this.subheaps = [];
}
function min(heap) {
return heap.elem;
//u and v are the two parameters of the surface between 0 and numPtsX
//ignoring boundary conditions
PVector bicubic(PVector[][] pts, float u, float v) {
//get indices
int uInd1 = int(u);
int uInd0 = uInd1-1;
int uInd2 = uInd1+1;
int uInd3 = uInd1+2;
float uVal = u-uInd1; //between 0..1
PVector[] offsetCurve(PVector[] crv, float dist) {
PVector[] offset = new PVector[crv.length];
for(int i=1;i<offset.length-1;++i) {
PVector currPt = crv[i];
PVector prevPt = crv[i-1];
PVector nextPt = crv[i+1];
PVector v1 = PVector.sub(prevPt,currPt);
PVector v2 = PVector.sub(nextPt,currPt);
v2.normalize();
v1.normalize();
PVector[] subdivide(PVector[] curve) {
//we add a midpoint for each segment, so we get twice as many points
PVector newCurve[] = new PVector[curve.length*2];
for(int i=0;i<curve.length;++i) {
PVector currPt = curve[i];
PVector prevPt = curve[(i-1+curve.length)%curve.length];
PVector nextPt = curve[(i+1)%curve.length];
newCurve[2*i] = new PVector();
newCurve[2*i].add(PVector.mult(prevPt,.125));
newCurve[2*i].add(PVector.mult(currPt,.75));
//simple marching cubes with some abstraction
float resolution = .1;
int cubeGrid[][][] = new int[int(worldX/resolution)][int(worldY/resolution)][int(worldZ/resolution)];
PVector pt = new PVector();
//for each grid point compute inside or outside
for(int i=0;i<cubeGrid.length;++i) {
for(int j=0;j<cubeGrid[0].length;++j) {
for(int k=0;k<cubeGrid[0][0].length;++k) {
pt.set(i*resolution,j*resolution,k*resolution); //current position
float val = colorFunction(pt); //evaluation color function at pt
//Simple, bad surface splatting. Actually difficult
//Does not check for degenerate cases
for(int i=0;i<points.size();++i) {
PVector pt = (PVector) points.get(i);
PVector normal = (PVector) normals.get(i);
//draw a circle oriented towards normal at pt
//get rotation angles
float theta = atan2(normal.y,normal.x); //angle around z axis
float psi = atan2(sqrt(normal.x*normal.x+normal.y*normal.y),normal.z); //angle from z axis
//get local axes
float FNext[][] = new float[F.length][F[0].length];
float r = deltaT*diffusionRate/deltaXSq;
for(int i=0;i<F.length;++i) {
for(int j=0;j<F[0].length;++j) {
//get the neighboring values with boundary conditions
float iPrev, iNext, jNext, jPrev;
if(i==0) iPrev = F[i][j];
else iPrev = F[i-1][j];
if(i==F.length-1) iNext = F[i][j];
else iNext = F[i+1][j];
for(int i=0;i<F.length;++i) {
for(int j=0;j<F[0].length;++j) {
F_next[i][j] = F[i][j]+deltaT*diffusionRate/deltaXSq*(F[(i+1)%F.length][j]+
F[(i-1+F.length)%F.length][j]+
F[i][(j+1)%F[0].length]+
F[i][(j-1+F[0].length)%F[0].length]-
4*F[i][j]);
}
}