inline std::tuple<MathLib::Point3d, MathLib::Point3d, MathLib::Point3d> getEdgeMiddlePoints(GeoLib::Triangle const& tri) { return std::make_tuple( getEdgeMiddlePoint(*tri.getPoint(0), *tri.getPoint(1)), getEdgeMiddlePoint(*tri.getPoint(1), *tri.getPoint(2)), getEdgeMiddlePoint(*tri.getPoint(2), *tri.getPoint(0))); }
double LinearInterpolationOnSurface::interpolateInTri(const GeoLib::Triangle &tri, double const* const vertex_values, double const* const pnt) const { std::vector<GeoLib::Point> pnts; for (unsigned i=0; i<3; i++) pnts.emplace_back(*tri.getPoint(i)); std::vector<GeoLib::Point*> p_pnts = {{&pnts[0], &pnts[1], &pnts[2]}}; GeoLib::rotatePointsToXY(p_pnts); GeoLib::Point const& v1(pnts[0]); GeoLib::Point const& v2(pnts[1]); GeoLib::Point const& v3(pnts[2]); const double area = GeoLib::calcTriangleArea(v1, v2, v3); if (area==.0) { // take average if all points have the same coordinates return std::accumulate(vertex_values, vertex_values+3, 0.0) / 3; } // interpolate as // u(x,y) = sum_i[N_i(x,y)*u_i] (i=1,2,3) // N_i(x,y) = 1/(2A)*(a_i + b_i*x + c_i*y) double a[3], b[3], c[3]; // 1st vertex a[0] = 0.5/area*(v2[0]*v3[1]-v3[0]*v2[1]); b[0] = 0.5/area*(v2[1]-v3[1]); c[0] = 0.5/area*(v3[0]-v2[0]); // 2nd vertex a[1] = 0.5/area*(v3[0]*v1[1]-v1[0]*v3[1]); b[1] = 0.5/area*(v3[1]-v1[1]); c[1] = 0.5/area*(v1[0]-v3[0]); // 3rd vertex a[2] = 0.5/area*(v1[0]*v2[1]-v2[0]*v1[1]); b[2] = 0.5/area*(v1[1]-v2[1]); c[2] = 0.5/area*(v2[0]-v1[0]); double val = .0; for (unsigned i=0; i<3; i++) val += (a[i]+b[i]*pnt[0]+c[i]*pnt[1]) * vertex_values[i]; return val; }