int16_t xyForGamutID(point_t *xy, int16_t gamutID, point_t *xy_r) { point_t triangle[3]; _triangleForGamutID(gamutID, triangle); if(_isPointInTriangle(xy, triangle)) { memcpy(xy_r,xy,sizeof(point_t)); return 0; } point_t pAB, pAC, pBC; _closestPointOnLine(&triangle[RED], &triangle[GREEN], xy, &pAB); _closestPointOnLine(&triangle[BLUE], &triangle[RED], xy, &pAC); _closestPointOnLine(&triangle[GREEN], &triangle[BLUE], xy, &pBC); float dAB = _distance(xy, &pAB); float dAC = _distance(xy, &pAC); float dBC = _distance(xy, &pBC); float lowest = dAB; point_t *closestPoint = &pAB; if(dAC < lowest) { lowest = dAC; closestPoint = &pAC; } if(dBC < lowest) { // lowest = dBC; closestPoint = &pBC; } xy_r->x = closestPoint->x; xy_r->y = closestPoint->y; return 0; }
KRVector3 KRTriangle3::closestPointOnTriangle(const KRVector3 &p) const { KRVector3 a = m_c[0]; KRVector3 b = m_c[1]; KRVector3 c = m_c[2]; KRVector3 Rab = _closestPointOnLine(a, b, p); KRVector3 Rbc = _closestPointOnLine(b, c, p); KRVector3 Rca = _closestPointOnLine(c, a, p); // return closest [Rab, Rbc, Rca] to p; float sd_Rab = (p - Rab).sqrMagnitude(); float sd_Rbc = (p - Rbc).sqrMagnitude(); float sd_Rca = (p - Rca).sqrMagnitude(); if(sd_Rab < sd_Rbc && sd_Rab < sd_Rca) { return Rab; } else if(sd_Rbc < sd_Rab && sd_Rbc < sd_Rca) { return Rbc; } else { return Rca; } }