void p2tr_math_triangle_circumcircle (const P2trVector2 *A, const P2trVector2 *B, const P2trVector2 *C, P2trCircle *circle) { /* | Ax Bx Cx | * D = + | Ay By Cy | * 2 * | +1 +1 +1 | * * | Asq Bsq Csq | * X = + | Ay By Cy | / D * | 1 1 1 | * * | Asq Bsq Csq | * Y = - | Ax Bx Cx | / D * | 1 1 1 | */ gdouble Asq = P2TR_VECTOR2_LEN_SQ (A); gdouble Bsq = P2TR_VECTOR2_LEN_SQ (B); gdouble Csq = P2TR_VECTOR2_LEN_SQ (C); gdouble invD = 1 / (2 * p2tr_matrix_det3 ( A->x, B->x, C->x, A->y, B->y, C->y, 1, 1, 1)); circle->center.x = + p2tr_matrix_det3 ( Asq, Bsq, Csq, A->y, B->y, C->y, 1, 1, 1) * invD; circle->center.y = - p2tr_matrix_det3 ( Asq, Bsq, Csq, A->x, B->x, C->x, 1, 1, 1) * invD; circle->radius = sqrt (P2TR_VECTOR2_DISTANCE_SQ (A, &circle->center)); }
static gboolean find_closest_intersection (P2trPSLG *pslg, P2trLine *line, P2trVector2 *close_to, P2trVector2 *dest) { gdouble distance_sq = G_MAXDOUBLE; gboolean found = FALSE; const P2trBoundedLine *pslg_line = NULL; P2trPSLGIter pslg_iter; P2trVector2 temp; p2tr_pslg_iter_init (&pslg_iter, pslg); while (p2tr_pslg_iter_next (&pslg_iter, &pslg_line)) { if (p2tr_line_intersection (&pslg_line->infinite, line, &temp) == P2TR_LINE_RELATION_INTERSECTING) { gdouble test_distance_sq = P2TR_VECTOR2_DISTANCE_SQ (&temp, close_to); found = TRUE; if (test_distance_sq < distance_sq) { distance_sq = test_distance_sq; } } } if (found && dest != NULL) p2tr_vector2_copy (dest, &temp); return found; }