Área orientada de um triângulo

Dados três pontos $p_1$, $p_2$ e $p_3$, calcule uma área orientada de um triângulo formado por eles. O sinal da área é determinado da seguinte maneira: imagine que você está no plano no ponto $p_1$ e está de frente com $p_2$. Você vai para $p_2$ e se $p_3$ estiver à sua direita (então dizemos que os três vetores giram no sentido horário), o sinal da área é positivo, caso contrário, é negativo. Se os três pontos são colineares, a área é zero.

Usando esta área com sinal, podemos obter a área regular sem sinal (como o valor absoluto($abs$) da área com sinal) e determinar se os pontos estão no sentido horário ou anti-horário na ordem especificada (o que é útil, por exemplo, em algoritmos de convex hull).

Cálculo

Podemos usar o fato de que um determinante de uma matriz $2\times 2$ é igual à área com sinal de um paralelogramo estendido pelos vetores da coluna (ou linha) da matriz. Isso é análogo à definição do produto vetorial em 2D (consulte este artigo). Ao dividir essa área por dois, obtemos a área de um triângulo em que estamos interessados. Usaremos $\vec{p_1p_2}$ e $\vec{p_2p_3}$ como vetores coluna e calcularemos um determinante $2\times 2$: $$2S=\left|\begin{matrix}x_2-x_1 & x_3-x_2\\y_2-y_1 & y_3-y_2\end{matrix}\right|=(x_2-x_1)(y_3-y_2)-(x_3-x_2)(y_2-y_1)$$

Implementação

int signed_area_parallelogram(point2d p1, point2d p2, point2d p3) {
    return cross(p2 - p1, p3 - p2);
}

double triangle_area(point2d p1, point2d p2, point2d p3) {
    return abs(signed_area_parallelogram(p1, p2, p3)) / 2.0;
}

bool clockwise(point2d p1, point2d p2, point2d p3) {
    return signed_area_parallelogram(p1, p2, p3) < 0;
}

bool counter_clockwise(point2d p1, point2d p2, point2d p3) {
    return signed_area_parallelogram(p1, p2, p3) > 0;
}

Problemas