Calculate the distance from a point[x,y] to a triangle [[x1, y1], [x2, y2], [x3, y3]], points are ordered in the counter-clockwise direction.
example:
input: [0, -2], [[0, 1], [1, -1], [-1, -1]]
output: [0, -2]
solution:
#include <iostream>
#include <cmath>
#include <algorithm>
double find_min(std::pair<float, float> a, std::pair<float, float> b, std::pair<float, float> p) {
std::pair<float, float> ab(b.first - a.first, b.second - a.second);
std::pair<float, float> ap(p.first - a.first, p.second - a.second);
std::pair<float, float> ba(a.first - b.first, a.second - b.second);
std::pair<float, float> bp(p.first - b.first, p.second - a.second);
if (ab.first * ap.first + ab.second * ap.second > 0 && ba.first * bp.first + ba.second * bp.second > 0) {
double cos_theta = (ab.first * ap.first + ab.second * ap.second) / (sqrt(ab.first * ab.first + ab.second * ab.second) * sqrt(ap.first * ap.first + ap.second * ap.second));
double sin_theta = sqrt(1 - cos_theta * cos_theta);
double dis = sqrt(ap.first * ap.first + ap.second * ap.second) * sin_theta;
return dis;
}
double dis_a = sqrt((p.first - a.first) * (p.first - a.first) + (p.second - a.second) * (p.second - a.second));
double dis_b = sqrt((p.first - b.first) * (p.first - b.first) + (p.second - b.second) * (p.second - b.second));
return std::min(dis_a, dis_b);
}
bool isPointInTriangle(std::pair<float, float> a, std::pair<float, float> b, std::pair<float, float> c, std::pair<float, float> p) {
std::pair<float, float> pa(a.first - p.first, a.second - p.second);
std::pair<float, float> pb(b.first - p.first, b.second - p.second);
std::pair<float, float> pc(c.first - p.first, c.second - p.second);
double t1 = pa.first * pb.second - pa.second * pb.first;
double t2 = pb.first * pc.second - pb.second * pc.first;
double t3 = pc.first * pa.second - pc.second * pa.first;
return ((t1 * t2 >= 0) && (t1 * t3 >= 0) && (t2 * t3 >= 0));
}
int main() {
std::pair<float, float> a(0, 1);
std::pair<float, float> b(1, -1);
std::pair<float, float> c(-1, -1);
std::pair<float, float> p(2, -2);
if (isPointInTriangle(a, b, c, p)) {
return 0;
}
double dis_a = find_min(a, b, p);
double dis_b = find_min(a, c, p);
double dis_p = find_min(b, c, p);
double res = std::min(dis_a, std::min(dis_b, dis_p));
std::cout << res;
return 0;
}