10 p2tr_edge_init (P2trEdge *self,
16 self->angle = atan2 (end->c.y - start->c.y,
17 end->c.x - start->c.x);
18 self->constrained = constrained;
19 self->delaunay = FALSE;
21 self->mirror = mirror;
27 p2tr_edge_new (P2trPoint *start,
31 P2trEdge *self = g_slice_new (P2trEdge);
32 P2trEdge *mirror = g_slice_new (P2trEdge);
34 p2tr_edge_init (self, start, end, constrained, mirror);
35 p2tr_edge_init (mirror, end, start, constrained, self);
37 p2tr_point_ref (start);
40 _p2tr_point_insert_edge (start, self);
41 _p2tr_point_insert_edge (end, mirror);
48 p2tr_edge_ref (P2trEdge *self)
54 p2tr_edge_unref (P2trEdge *self)
56 if (--self->refcount == 0 && self->mirror->refcount == 0)
57 p2tr_edge_free (self);
61 p2tr_edge_is_removed (P2trEdge *self)
63 return self->end == NULL;
67 p2tr_edge_remove (P2trEdge *self)
70 P2trPoint *start, *end;
72 if (self->end == NULL) /* This is only true if the edge was removed */
75 mesh = p2tr_edge_get_mesh (self);
77 start = P2TR_EDGE_START(self);
80 if (self->tri != NULL)
81 p2tr_triangle_remove (self->tri);
82 if (self->mirror->tri != NULL)
83 p2tr_triangle_remove (self->mirror->tri);
85 _p2tr_point_remove_edge(start, self);
86 _p2tr_point_remove_edge(end, self->mirror);
89 self->mirror->end = NULL;
91 p2tr_point_unref (start);
92 p2tr_point_unref (end);
96 p2tr_mesh_on_edge_removed (mesh, self);
97 p2tr_mesh_on_edge_removed (mesh, self->mirror);
102 p2tr_edge_free (P2trEdge *self)
104 p2tr_edge_remove (self);
105 g_slice_free (P2trEdge, self);
106 g_slice_free (P2trEdge, self->mirror);
110 p2tr_edge_get_diametral_circle (P2trEdge *self,
115 p2tr_vector2_center (&self->end->c, &P2TR_EDGE_START(self)->c, &circle->center);
116 p2tr_vector2_sub (&self->end->c, &circle->center, &radius);
118 circle->radius = p2tr_vector2_norm (&radius);
122 p2tr_edge_get_mesh (P2trEdge *self)
124 if (self->end != NULL)
125 return self->end->mesh;
131 p2tr_edge_get_length(P2trEdge* self)
133 return sqrt (p2tr_math_length_sq2 (&self->end->c, &P2TR_EDGE_START(self)->c));
137 p2tr_edge_get_length_squared(P2trEdge* self)
139 return p2tr_math_length_sq2 (&self->end->c, &P2TR_EDGE_START(self)->c);
143 p2tr_edge_angle_between(P2trEdge *e1, P2trEdge *e2)
145 /* A = E1.angle, a = abs (A)
146 * B = E1.angle, b = abs (B)
148 * W is the angle we wish to find. Note the fact that we want
149 * to find the angle so that the edges go CLOCKWISE around it.
151 * Case 1: Signs of A and B agree | Case 2: Signs of A and B disagree
152 * and A > 0 | and A > 0
154 * a = A, b = B | a = A, b = -B
159 * - - - - * - |W- - - - - - - - | - - - - * - - - -
162 * E1 ||\ | E1 // \_/ \\ E2
164 * - - - - - - | // vv
166 * W = A' + B = (180 - A) + B | W = 180 - (a + b) = 180 - (A - B)
167 * W = 180 - A + B | W = 180 - A + B
169 * By the illustration above, we can see that in general the angle W
170 * can be computed by W = 180 - A + B in every case. The only thing to
171 * note is that the range of the result of the computation is
172 * [180 - 360, 180 + 360] = [-180, +540] so we may need to subtract
173 * 360 to put it back in the range [-180, +180].
177 if (e1->end != P2TR_EDGE_START(e2))
178 p2tr_exception_programmatic ("The end-point of the first edge isn't"
179 " the end-point of the second edge!");
181 result = G_PI - e1->angle + e2->angle;
182 if (result > 2 * G_PI)