Skip to content

Instantly share code, notes, and snippets.

@larsberg
Last active August 29, 2015 14:04
Show Gist options
  • Save larsberg/7abe38db2110ecad58ab to your computer and use it in GitHub Desktop.
Save larsberg/7abe38db2110ecad58ab to your computer and use it in GitHub Desktop.
Evenly distributed randome points on an ofMesh
#pragma once
#include "ofMain.h"
namespace RandomPointsOnMesh
{
static float areaOfTriangle(ofVec3f p0, ofVec3f p1, ofVec3f p2)
{
return (p2 - p1).cross(p0 - p1).length() * .5;
}
template <class T>
static T pointInTriangle(T t0, T t1, T t2 , float u, float v)
{
if( ( u + v ) > 1 )
{
u = 1. - u;
v = 1. - v;
}
return t0 * u + t1 * v + t2 * (1 - u - v);
}
class Face3
{
public:
Face3(ofVec3f a, ofVec3f b, ofVec3f c) :
a(a), b(b), c(c), area(areaOfTriangle(a,b,c))
{};
static bool compareAreas(Face3 a, Face3 b )
{
return a.area < b.area;
}
ofVec3f a, b, c;
float area, normalizedArea, u;
};
static vector<Face3> getSortedAndWeightedMeshFaces(ofMesh& mesh, bool normalizeFaceAreas = true)
{
vector<Face3> faces;
float totalArea = 0;
//create our faces
if(mesh.getIndices().size() == 0)
{
auto& v = mesh.getVertices();
for(int i=0; i<v.size(); i+=3)
{
Face3 f(v[i], v[i+1], v[i+2]);
totalArea += f.area;
faces.push_back(f);
}
}
else
{
auto& v = mesh.getVertices();
auto& indices = mesh.getIndices();
for(int i=0; i<indices.size(); i+=3)
{
Face3 f(v[indices[i]], v[indices[i+1]], v[indices[i+2]]);
totalArea += f.area;
faces.push_back(f);
}
}
//sort the faces by area
sort(faces.begin(), faces.end(), Face3::compareAreas);
//get the normalized face areas and a 'u' sampling value
float u = 0;
for(auto &f: faces)
{
f.normalizedArea = f.area / totalArea;
u += f.normalizedArea;
f.u = u;
}
return faces;
}
static vector<ofVec3f> getRandomSurfacePoints(ofMesh& mesh, int numPoints = 100000, float scale = 1.)
{
vector<ofVec3f> points(numPoints);
//get our faces
auto faces = getSortedAndWeightedMeshFaces(mesh, true);
//find a bunch of random points on the surface
for(auto &p: points)
{
float lowThreshold = ofRandom(0., 1.);
for(auto& f: faces)
{
if(lowThreshold < f.u)
{
p = pointInTriangle(f.a, f.b, f.c, ofRandom(0.,1.), ofRandom(0.,1.)) * scale;
break;
}
}
}
return points;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment