angle between face detector

This commit is contained in:
Trammell Hudson 2015-02-14 19:11:52 -05:00
parent 04d9604106
commit 1e490d05f7
2 changed files with 57 additions and 175 deletions

179
corners.c
View File

@ -17,177 +17,8 @@ static int debug = 0;
static int draw_labels = 0;
#if 0
/* Returns 1 for ever edge in f1 that is shared with f2.
*/
int
coplanar_check(
const stl_face_t * const f1,
const stl_face_t * const f2
)
{
// Verify that there are three matching points
int match[3] = {0,0,0};
for (int i = 0 ; i < 3 ; i++)
{
for (int j = 0 ; j < 3 ; j++)
if (v3_eq(&f1->p[i], &f2->p[j]))
match[i] = 1;
}
uint8_t mask = 0;
if (match[0] && match[1])
mask = 1;
if (match[1] && match[2])
mask = 2;
if (match[2] && match[0])
mask = 4;
if (debug)
fprintf(stderr, "%p %p: %d %d %d\n",
f1,
f2,
match[0], match[1], match[2]
);
// otherwise they do not share enough points
if (mask == 0)
return 0;
#if 0
// find the four distinct points
v3_t x1 = f1->p[0];
v3_t x2 = f1->p[1];
v3_t x3 = f1->p[2];
v3_t x4;
for (int i = 0 ; i < 3 ; i++)
{
x4 = f2->p[i];
if (v3_eq(&x1, &x4))
continue;
if (v3_eq(&x2, &x4))
continue;
if (v3_eq(&x3, &x4))
continue;
break;
}
// (x3-x1) . ((x2-x1) X (x4-x3)) == 0
v3_t dx31 = v3_sub(x3, x1);
v3_t dx21 = v3_sub(x2, x1);
v3_t dx43 = v3_sub(x4, x3);
v3_t cross = v3_cross(dx21, dx43);
float dot = v3_dot(dx31, cross);
if (debug)
fprintf(stderr, "dot %f:\n %f,%f,%f\n %f,%f,%f\n %f,%f,%f\n %f,%f,%f\n",
dot,
x1.p[0], x1.p[1], x1.p[2],
x2.p[0], x2.p[1], x2.p[2],
x3.p[0], x3.p[1], x3.p[2],
x4.p[0], x4.p[1], x4.p[2]
);
int check = -EPS < dot && dot < +EPS;
// if the dot product is not close enough to zero, they
// are not coplanar.
if (!check)
return 0;
// coplanar! return the shared edge mask
return mask;
#else
// if the normals are close enough, then it is coplanner
if (v3_eq(&f1->normal, &f2->normal))
return mask;
else
return 0;
#endif
}
static inline float
sign(
const float x
)
{
if (x < 0)
return -1;
if (x > 0)
return +1;
return 0;
}
/**
* Add a vector to the list of edges if it is not already present
* and if it is not coplanar with other ones.
* Note that if it is coplanar, but "outside" the other edges then it
* will replace the inside one.
*/
void
stl_edge_insert(
stl_vertex_t * const v1,
stl_vertex_t * const v2
)
{
for (int i = 0 ; i < v1->num_edges ; i++)
{
// if v2 already exists in the edges, discard it
if (v1->edges[i] == v2)
return;
}
// if we reach this point, we need to insert the edge
if (debug)
fprintf(stderr, "%p: edge %d -> %p\n",
v1,
v1->num_edges,
v2
);
v1->edges[v1->num_edges++] = v2;
}
/** Find or create a vertex */
stl_vertex_t *
stl_vertex_find(
stl_vertex_t ** const vertices,
int * num_vertex_ptr,
const v3_t * const p
)
{
const int num_vertex = *num_vertex_ptr;
for (int x = 0 ; x < num_vertex ; x++)
{
stl_vertex_t * const v = vertices[x];
if (v3_eq(&v->p, p))
return v;
}
if (debug)
fprintf(stderr, "%d: %f,%f,%f\n",
num_vertex,
p->p[0],
p->p[1],
p->p[2]
);
stl_vertex_t * const v = vertices[(*num_vertex_ptr)++] = calloc(1, sizeof(*v));
v->p = *p;
return v;
}
#endif
int main(void)
main(void)
{
stl_3d_t * const stl = stl_3d_parse(STDIN_FILENO);
if (!stl)
@ -206,11 +37,11 @@ int main(void)
{
const stl_face_t * const f = v->face[j];
fprintf(stderr, "\t%d: %d,%d,%d\n",
fprintf(stderr, "\t%d: %d:%f,%d:%f,%d:%f\n",
f - stl->face,
f->face[0] ? f->face[0] - stl->face : -1,
f->face[1] ? f->face[1] - stl->face : -1,
f->face[2] ? f->face[2] - stl->face : -1
f->face[0] ? f->face[0] - stl->face : -1, f->angle[0],
f->face[1] ? f->face[1] - stl->face : -1, f->angle[1],
f->face[2] ? f->face[2] - stl->face : -1, f->angle[2]
);
}
}

View File

@ -57,6 +57,9 @@ stl_vertex_find(
}
/** Check to see if the two faces share an edge.
* \return 0 if no common edge, 1 if there is a shared link
*/
static int
stl_has_edge(
const stl_face_t * const f,
@ -73,13 +76,61 @@ stl_has_edge(
}
/** Compute the angle between the two planes.
* This is an approximation:
* \return 0 == coplanar, negative == valley, positive == mountain.
*/
static double
stl_angle(
const stl_face_t * const f1,
const stl_face_t * const f2
)
{
// find the four distinct points
v3_t x1 = f1->vertex[0]->p;
v3_t x2 = f1->vertex[1]->p;
v3_t x3 = f1->vertex[2]->p;
v3_t x4;
for (int i = 0 ; i < 3 ; i++)
{
x4 = f2->vertex[i]->p;
if (v3_eq(&x1, &x4))
continue;
if (v3_eq(&x2, &x4))
continue;
if (v3_eq(&x3, &x4))
continue;
break;
}
// (x3-x1) . ((x2-x1) X (x4-x3)) == 0
v3_t dx31 = v3_sub(x3, x1);
v3_t dx21 = v3_sub(x2, x1);
v3_t dx43 = v3_sub(x4, x3);
v3_t cross = v3_cross(dx21, dx43);
float dot = v3_dot(dx31, cross);
if (debug)
fprintf(stderr, "dot %f:\n %f,%f,%f\n %f,%f,%f\n %f,%f,%f\n %f,%f,%f\n",
dot,
x1.p[0], x1.p[1], x1.p[2],
x2.p[0], x2.p[1], x2.p[2],
x3.p[0], x3.p[1], x3.p[2],
x4.p[0], x4.p[1], x4.p[2]
);
int check = -EPS < dot && dot < +EPS;
// if the dot product is not close enough to zero, they
// are not coplanar.
if (check)
return 0;
if (dot < 0)
return -1;
else
return +1;
}