📄 triangle.c
字号:
/* *//* lnext: Find the next edge (counterclockwise) of a triangle. *//* lnext(abc) -> bca *//* *//* lprev: Find the previous edge (clockwise) of a triangle. *//* lprev(abc) -> cab *//* *//* onext: Find the next edge counterclockwise with the same origin. *//* onext(abc) -> ac* *//* *//* oprev: Find the next edge clockwise with the same origin. *//* oprev(abc) -> a*b *//* *//* dnext: Find the next edge counterclockwise with the same destination. *//* dnext(abc) -> *ba *//* *//* dprev: Find the next edge clockwise with the same destination. *//* dprev(abc) -> cb* *//* *//* rnext: Find the next edge (counterclockwise) of the adjacent triangle. *//* rnext(abc) -> *a* *//* *//* rprev: Find the previous edge (clockwise) of the adjacent triangle. *//* rprev(abc) -> b** *//* *//* org: Origin dest: Destination apex: Apex *//* org(abc) -> a dest(abc) -> b apex(abc) -> c *//* *//* bond: Bond two triangles together at the resepective handles. *//* bond(abc, bad) *//* *//* *//* For subsegments: *//* *//* ssym: Reverse the orientation of a subsegment. *//* ssym(ab) -> ba *//* *//* spivot: Find adjoining subsegment with the same origin. *//* spivot(ab) -> a* *//* *//* snext: Find next subsegment in sequence. *//* snext(ab) -> b* *//* *//* sorg: Origin sdest: Destination *//* sorg(ab) -> a sdest(ab) -> b *//* *//* sbond: Bond two subsegments together at the respective origins. *//* sbond(ab, ac) *//* *//* *//* For interacting tetrahedra and subfacets: *//* *//* tspivot: Find a subsegment abutting a triangle. *//* tspivot(abc) -> ba *//* *//* stpivot: Find a triangle abutting a subsegment. *//* stpivot(ab) -> ba* *//* *//* tsbond: Bond a triangle to a subsegment. *//* tsbond(abc, ba) *//* *//*****************************************************************************//********* Mesh manipulation primitives begin here *********//** **//** **//* Fast lookup arrays to speed some of the mesh manipulation primitives. */int plus1mod3[3] = {1, 2, 0};int minus1mod3[3] = {2, 0, 1};/********* Primitives for triangles *********//* *//* *//* decode() converts a pointer to an oriented triangle. The orientation is *//* extracted from the two least significant bits of the pointer. */#define decode(ptr, otri) \ (otri).orient = (int) ((unsigned long) (ptr) & (unsigned long) 3l); \ (otri).tri = (triangle *) \ ((unsigned long) (ptr) ^ (unsigned long) (otri).orient)/* encode() compresses an oriented triangle into a single pointer. It *//* relies on the assumption that all triangles are aligned to four-byte *//* boundaries, so the two least significant bits of (otri).tri are zero. */#define encode(otri) \ (triangle) ((unsigned long) (otri).tri | (unsigned long) (otri).orient)/* The following handle manipulation primitives are all described by Guibas *//* and Stolfi. However, Guibas and Stolfi use an edge-based data *//* structure, whereas I use a triangle-based data structure. *//* sym() finds the abutting triangle, on the same edge. Note that the edge *//* direction is necessarily reversed, because the handle specified by an *//* oriented triangle is directed counterclockwise around the triangle. */#define sym(otri1, otri2) \ ptr = (otri1).tri[(otri1).orient]; \ decode(ptr, otri2);#define symself(otri) \ ptr = (otri).tri[(otri).orient]; \ decode(ptr, otri);/* lnext() finds the next edge (counterclockwise) of a triangle. */#define lnext(otri1, otri2) \ (otri2).tri = (otri1).tri; \ (otri2).orient = plus1mod3[(otri1).orient]#define lnextself(otri) \ (otri).orient = plus1mod3[(otri).orient]/* lprev() finds the previous edge (clockwise) of a triangle. */#define lprev(otri1, otri2) \ (otri2).tri = (otri1).tri; \ (otri2).orient = minus1mod3[(otri1).orient]#define lprevself(otri) \ (otri).orient = minus1mod3[(otri).orient]/* onext() spins counterclockwise around a vertex; that is, it finds the *//* next edge with the same origin in the counterclockwise direction. This *//* edge is part of a different triangle. */#define onext(otri1, otri2) \ lprev(otri1, otri2); \ symself(otri2);#define onextself(otri) \ lprevself(otri); \ symself(otri);/* oprev() spins clockwise around a vertex; that is, it finds the next edge *//* with the same origin in the clockwise direction. This edge is part of *//* a different triangle. */#define oprev(otri1, otri2) \ sym(otri1, otri2); \ lnextself(otri2);#define oprevself(otri) \ symself(otri); \ lnextself(otri);/* dnext() spins counterclockwise around a vertex; that is, it finds the *//* next edge with the same destination in the counterclockwise direction. *//* This edge is part of a different triangle. */#define dnext(otri1, otri2) \ sym(otri1, otri2); \ lprevself(otri2);#define dnextself(otri) \ symself(otri); \ lprevself(otri);/* dprev() spins clockwise around a vertex; that is, it finds the next edge *//* with the same destination in the clockwise direction. This edge is *//* part of a different triangle. */#define dprev(otri1, otri2) \ lnext(otri1, otri2); \ symself(otri2);#define dprevself(otri) \ lnextself(otri); \ symself(otri);/* rnext() moves one edge counterclockwise about the adjacent triangle. *//* (It's best understood by reading Guibas and Stolfi. It involves *//* changing triangles twice.) */#define rnext(otri1, otri2) \ sym(otri1, otri2); \ lnextself(otri2); \ symself(otri2);#define rnextself(otri) \ symself(otri); \ lnextself(otri); \ symself(otri);/* rprev() moves one edge clockwise about the adjacent triangle. *//* (It's best understood by reading Guibas and Stolfi. It involves *//* changing triangles twice.) */#define rprev(otri1, otri2) \ sym(otri1, otri2); \ lprevself(otri2); \ symself(otri2);#define rprevself(otri) \ symself(otri); \ lprevself(otri); \ symself(otri);/* These primitives determine or set the origin, destination, or apex of a *//* triangle. */#define org(otri, vertexptr) \ vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3]#define dest(otri, vertexptr) \ vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3]#define apex(otri, vertexptr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -