angle between face detector
This commit is contained in:
parent
04d9604106
commit
1e490d05f7
179
corners.c
179
corners.c
@ -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]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
51
stl_3d.c
51
stl_3d.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user