move inset into stl_3d
This commit is contained in:
parent
a6a08bf10a
commit
b5210c4d65
137
faces.c
137
faces.c
@ -57,141 +57,6 @@ svg_circle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Determines the intersection point of the line defined by points A and B with the
|
|
||||||
// line defined by points C and D.
|
|
||||||
//
|
|
||||||
// Returns YES if the intersection point was found, and stores that point in X,Y.
|
|
||||||
// Returns NO if there is no determinable intersection point, in which case X,Y will
|
|
||||||
// be unmodified.
|
|
||||||
|
|
||||||
static int
|
|
||||||
line_intersect(
|
|
||||||
double Ax, double Ay,
|
|
||||||
double Bx, double By,
|
|
||||||
double Cx, double Cy,
|
|
||||||
double Dx, double Dy,
|
|
||||||
double *X, double *Y
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Fail if either line is undefined.
|
|
||||||
if ((Ax==Bx && Ay==By) || (Cx==Dx && Cy==Dy))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// (1) Translate the system so that point A is on the origin.
|
|
||||||
Bx-=Ax; By-=Ay;
|
|
||||||
Cx-=Ax; Cy-=Ay;
|
|
||||||
Dx-=Ax; Dy-=Ay;
|
|
||||||
|
|
||||||
// Discover the length of segment A-B.
|
|
||||||
const double distAB=sqrt(Bx*Bx+By*By);
|
|
||||||
|
|
||||||
// (2) Rotate the system so that point B is on the positive X axis.
|
|
||||||
const double theCos=Bx/distAB;
|
|
||||||
const double theSin=By/distAB;
|
|
||||||
|
|
||||||
double newX=Cx*theCos+Cy*theSin;
|
|
||||||
Cy =Cy*theCos-Cx*theSin; Cx=newX;
|
|
||||||
newX=Dx*theCos+Dy*theSin;
|
|
||||||
Dy =Dy*theCos-Dx*theSin; Dx=newX;
|
|
||||||
|
|
||||||
// Fail if the lines are parallel.
|
|
||||||
if (Cy==Dy) return 0;
|
|
||||||
|
|
||||||
// (3) Discover the position of the intersection point along line A-B.
|
|
||||||
const double ABpos=Dx+(Cx-Dx)*Dy/(Dy-Cy);
|
|
||||||
|
|
||||||
// (4) Apply the discovered position to line A-B in the original coordinate system.
|
|
||||||
*X=Ax+ABpos*theCos;
|
|
||||||
*Y=Ay+ABpos*theSin;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Compute the inset coordinate.
|
|
||||||
* http://alienryderflex.com/polygon_inset/
|
|
||||||
// Given the sequentially connected points (a,b), (c,d), and (e,f), this
|
|
||||||
// function returns, in (C,D), a bevel-inset replacement for point (c,d).
|
|
||||||
//
|
|
||||||
// Note: If vectors (a,b)->(c,d) and (c,d)->(e,f) are exactly 180° opposed,
|
|
||||||
// or if either segment is zero-length, this function will do
|
|
||||||
// nothing; i.e. point (C,D) will not be set.
|
|
||||||
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
inset(
|
|
||||||
const refframe_t * const ref,
|
|
||||||
const double inset_dist,
|
|
||||||
double * const x_out,
|
|
||||||
double * const y_out,
|
|
||||||
const v3_t p0, // previous point
|
|
||||||
const v3_t p1, // current point to inset
|
|
||||||
const v3_t p2 // next point
|
|
||||||
)
|
|
||||||
{
|
|
||||||
double a, b, c, d, e, f;
|
|
||||||
v3_project(ref, p0, &a, &b);
|
|
||||||
v3_project(ref, p1, &c, &d);
|
|
||||||
v3_project(ref, p2, &e, &f);
|
|
||||||
|
|
||||||
double c1 = c;
|
|
||||||
double d1 = d;
|
|
||||||
double c2 = c;
|
|
||||||
double d2 = d;
|
|
||||||
|
|
||||||
// Calculate length of line segments.
|
|
||||||
const double dx1 = c-a;
|
|
||||||
const double dy1 = d-b;
|
|
||||||
const double dist1 = sqrt(dx1*dx1+dy1*dy1);
|
|
||||||
const double dx2 = e-c;
|
|
||||||
const double dy2 = f-d;
|
|
||||||
const double dist2 = sqrt(dx2*dx2+dy2*dy2);
|
|
||||||
|
|
||||||
// Exit if either segment is zero-length.
|
|
||||||
if (dist1==0. || dist2==0.)
|
|
||||||
{
|
|
||||||
*x_out = *y_out = 0;
|
|
||||||
fprintf(stderr, "inset fail\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inset each of the two line segments.
|
|
||||||
double insetX, insetY;
|
|
||||||
|
|
||||||
insetX = dy1/dist1 * inset_dist;
|
|
||||||
a+=insetX;
|
|
||||||
c1+=insetX;
|
|
||||||
|
|
||||||
insetY = -dx1/dist1 * inset_dist;
|
|
||||||
b+=insetY;
|
|
||||||
d1+=insetY;
|
|
||||||
|
|
||||||
insetX = dy2/dist2 * inset_dist;
|
|
||||||
e+=insetX;
|
|
||||||
c2+=insetX;
|
|
||||||
|
|
||||||
insetY = -dx2/dist2 * inset_dist;
|
|
||||||
f+=insetY;
|
|
||||||
d2+=insetY;
|
|
||||||
|
|
||||||
// If inset segments connect perfectly, return the connection point.
|
|
||||||
if (c1==c2 && d1==d2)
|
|
||||||
{
|
|
||||||
*x_out = c1;
|
|
||||||
*y_out = d1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the intersection point of the two inset segments (if any).
|
|
||||||
if (line_intersect(a,b,c1,d1,c2,d2,e,f, x_out, y_out))
|
|
||||||
return;
|
|
||||||
|
|
||||||
*x_out = *y_out = 0;
|
|
||||||
fprintf(stderr, "inset failed 2\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
@ -247,7 +112,7 @@ main(void)
|
|||||||
for (int j = 0 ; j < vertex_count ; j++)
|
for (int j = 0 ; j < vertex_count ; j++)
|
||||||
{
|
{
|
||||||
double x, y;
|
double x, y;
|
||||||
inset(&ref, inset_distance, &x, &y,
|
refframe_inset(&ref, inset_distance, &x, &y,
|
||||||
vertex_list[(j+0) % vertex_count]->p,
|
vertex_list[(j+0) % vertex_count]->p,
|
||||||
vertex_list[(j+1) % vertex_count]->p,
|
vertex_list[(j+1) % vertex_count]->p,
|
||||||
vertex_list[(j+2) % vertex_count]->p
|
vertex_list[(j+2) % vertex_count]->p
|
||||||
|
133
stl_3d.c
133
stl_3d.c
@ -335,3 +335,136 @@ v3_project(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Determines the intersection point of the line defined by points A and B with the
|
||||||
|
// line defined by points C and D.
|
||||||
|
//
|
||||||
|
// Returns YES if the intersection point was found, and stores that point in X,Y.
|
||||||
|
// Returns NO if there is no determinable intersection point, in which case X,Y will
|
||||||
|
// be unmodified.
|
||||||
|
|
||||||
|
static int
|
||||||
|
line_intersect(
|
||||||
|
double Ax, double Ay,
|
||||||
|
double Bx, double By,
|
||||||
|
double Cx, double Cy,
|
||||||
|
double Dx, double Dy,
|
||||||
|
double *X, double *Y
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Fail if either line is undefined.
|
||||||
|
if ((Ax==Bx && Ay==By) || (Cx==Dx && Cy==Dy))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// (1) Translate the system so that point A is on the origin.
|
||||||
|
Bx-=Ax; By-=Ay;
|
||||||
|
Cx-=Ax; Cy-=Ay;
|
||||||
|
Dx-=Ax; Dy-=Ay;
|
||||||
|
|
||||||
|
// Discover the length of segment A-B.
|
||||||
|
const double distAB=sqrt(Bx*Bx+By*By);
|
||||||
|
|
||||||
|
// (2) Rotate the system so that point B is on the positive X axis.
|
||||||
|
const double theCos=Bx/distAB;
|
||||||
|
const double theSin=By/distAB;
|
||||||
|
|
||||||
|
double newX=Cx*theCos+Cy*theSin;
|
||||||
|
Cy =Cy*theCos-Cx*theSin; Cx=newX;
|
||||||
|
newX=Dx*theCos+Dy*theSin;
|
||||||
|
Dy =Dy*theCos-Dx*theSin; Dx=newX;
|
||||||
|
|
||||||
|
// Fail if the lines are parallel.
|
||||||
|
if (Cy==Dy) return 0;
|
||||||
|
|
||||||
|
// (3) Discover the position of the intersection point along line A-B.
|
||||||
|
const double ABpos=Dx+(Cx-Dx)*Dy/(Dy-Cy);
|
||||||
|
|
||||||
|
// (4) Apply the discovered position to line A-B in the original coordinate system.
|
||||||
|
*X=Ax+ABpos*theCos;
|
||||||
|
*Y=Ay+ABpos*theSin;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Compute the inset coordinate.
|
||||||
|
* http://alienryderflex.com/polygon_inset/
|
||||||
|
// Given the sequentially connected points (a,b), (c,d), and (e,f), this
|
||||||
|
// function returns, in (C,D), a bevel-inset replacement for point (c,d).
|
||||||
|
//
|
||||||
|
// Note: If vectors (a,b)->(c,d) and (c,d)->(e,f) are exactly 180° opposed,
|
||||||
|
// or if either segment is zero-length, this function will do
|
||||||
|
// nothing; i.e. point (C,D) will not be set.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
refframe_inset(
|
||||||
|
const refframe_t * const ref,
|
||||||
|
const double inset_dist,
|
||||||
|
double * const x_out,
|
||||||
|
double * const y_out,
|
||||||
|
const v3_t p0, // previous point
|
||||||
|
const v3_t p1, // current point to inset
|
||||||
|
const v3_t p2 // next point
|
||||||
|
)
|
||||||
|
{
|
||||||
|
double a, b, c, d, e, f;
|
||||||
|
v3_project(ref, p0, &a, &b);
|
||||||
|
v3_project(ref, p1, &c, &d);
|
||||||
|
v3_project(ref, p2, &e, &f);
|
||||||
|
|
||||||
|
double c1 = c;
|
||||||
|
double d1 = d;
|
||||||
|
double c2 = c;
|
||||||
|
double d2 = d;
|
||||||
|
|
||||||
|
// Calculate length of line segments.
|
||||||
|
const double dx1 = c-a;
|
||||||
|
const double dy1 = d-b;
|
||||||
|
const double dist1 = sqrt(dx1*dx1+dy1*dy1);
|
||||||
|
const double dx2 = e-c;
|
||||||
|
const double dy2 = f-d;
|
||||||
|
const double dist2 = sqrt(dx2*dx2+dy2*dy2);
|
||||||
|
|
||||||
|
// Exit if either segment is zero-length.
|
||||||
|
if (dist1==0. || dist2==0.)
|
||||||
|
{
|
||||||
|
*x_out = *y_out = 0;
|
||||||
|
fprintf(stderr, "inset fail\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inset each of the two line segments.
|
||||||
|
double insetX, insetY;
|
||||||
|
|
||||||
|
insetX = dy1/dist1 * inset_dist;
|
||||||
|
a+=insetX;
|
||||||
|
c1+=insetX;
|
||||||
|
|
||||||
|
insetY = -dx1/dist1 * inset_dist;
|
||||||
|
b+=insetY;
|
||||||
|
d1+=insetY;
|
||||||
|
|
||||||
|
insetX = dy2/dist2 * inset_dist;
|
||||||
|
e+=insetX;
|
||||||
|
c2+=insetX;
|
||||||
|
|
||||||
|
insetY = -dx2/dist2 * inset_dist;
|
||||||
|
f+=insetY;
|
||||||
|
d2+=insetY;
|
||||||
|
|
||||||
|
// If inset segments connect perfectly, return the connection point.
|
||||||
|
if (c1==c2 && d1==d2)
|
||||||
|
{
|
||||||
|
*x_out = c1;
|
||||||
|
*y_out = d1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the intersection point of the two inset segments (if any).
|
||||||
|
if (line_intersect(a,b,c1,d1,c2,d2,e,f, x_out, y_out))
|
||||||
|
return;
|
||||||
|
|
||||||
|
*x_out = *y_out = 0;
|
||||||
|
fprintf(stderr, "inset failed 2\n");
|
||||||
|
}
|
||||||
|
11
stl_3d.h
11
stl_3d.h
@ -82,6 +82,17 @@ refframe_init(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
refframe_inset(
|
||||||
|
const refframe_t * const ref,
|
||||||
|
const double inset_dist,
|
||||||
|
double * const x_out,
|
||||||
|
double * const y_out,
|
||||||
|
const v3_t p0, // previous point
|
||||||
|
const v3_t p1, // current point to inset
|
||||||
|
const v3_t p2 // next point
|
||||||
|
);
|
||||||
|
|
||||||
/** Project a 3D point onto a 2D space */
|
/** Project a 3D point onto a 2D space */
|
||||||
void
|
void
|
||||||
v3_project(
|
v3_project(
|
||||||
|
Loading…
Reference in New Issue
Block a user