二维代码:
// P(x, y) A(x1, y1) B(x2, y2)
public static double PointToSegDist(double x, double y, double x1, double y1, double x2, double y2)
{
double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
if (cross <= 0) return Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (cross >= d2) return Math.Sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
double r = cross / d2;
double px = x1 + (x2 - x1) * r;
double py = y1 + (y2 - y1) * r;
return Math.Sqrt((px - x) * (px - x) + (py - y) * (py - y));
}
三维代码:
// 点到线段的距离
double CTestDlg1::PointToSegDist(ProVector pntP, ProVector pntA, ProVector pntB)
{
double cross = (pntB[0] - pntA[0])*(pntP[0] - pntA[0]) + (pntB[1] - pntA[1])*(pntP[1] - pntA[1]) + (pntB[2] - pntA[2])*(pntP[2] - pntA[2]);
if (cross <= 0)
return sqrt((pntP[0] - pntA[0])*(pntP[0] - pntA[0]) + (pntP[1] - pntA[1])*(pntP[1] - pntA[1]) + (pntP[2] - pntA[2])*(pntP[2] - pntA[2]));
double d2 = (pntB[0] - pntA[0])*(pntB[0] - pntA[0]) + (pntB[1] - pntA[1])*(pntB[1] - pntA[1]) + (pntB[2] - pntA[2])*(pntB[2] - pntA[2]);
if (cross >= d2)
return sqrt((pntP[0] - pntB[0])*(pntP[0] - pntB[0]) + (pntP[1] - pntB[1])*(pntP[1] - pntB[1]) + (pntP[2] - pntB[2])*(pntP[2] - pntB[2]));
double r = cross / d2;
double px = pntA[0] + (pntB[0] - pntA[0]) * r;
double py = pntA[1] + (pntB[1] - pntA[1]) * r;
double pz = pntA[2] + (pntB[2] - pntA[2]) * r;
return
sqrt((pntP[0] - px) * (pntP[0] - px) + (pntP[1] - py) * (pntP[1] - py) + (pntP[2] - pz) * (pntP[2] - pz));
}
选择点、边:
void UsrProPntToSegmentDist()
{
ProError err;
ProSelection *p_sel;
int n_sel, num1 = 0, num2 = 0;
ProModelitem modelitem;
ProVector pntpnt, edgepnt1, edgepnt2;
ProGeomitemdata *p_data;
double dist = 0;
err = ProSelect("point,edge", 2, NULL, NULL, NULL, NULL, &p_sel, &n_sel);
if (err != PRO_TK_NO_ERROR) return;
for (int i = 0; i < n_sel; i ++)
{
err = ProSelectionModelitemGet(p_sel[i], &modelitem);
if (err != PRO_TK_NO_ERROR) return;
if (modelitem.type == PRO_POINT)
{
err = ProSelectionPoint3dGet(p_sel[i], pntpnt);
if (err != PRO_TK_NO_ERROR) return;
num1 = 1;
}
}
for (int i = 0; i < n_sel; i ++)
{
err = ProSelectionModelitemGet(p_sel[i], &modelitem);
if (err != PRO_TK_NO_ERROR) return;
if (modelitem.type == PRO_EDGE)
{
err = ProGeomitemdataGet((ProGeomitem*)&modelitem, &p_data);
if (err != PRO_TK_NO_ERROR) return;
edgepnt1[0] = p_data->data.p_curve_data->line.end1[0];
edgepnt1[1] = p_data->data.p_curve_data->line.end1[1];
edgepnt1[2] = p_data->data.p_curve_data->line.end1[2];
edgepnt2[0] = p_data->data.p_curve_data->line.end2[0];
edgepnt2[1] = p_data->data.p_curve_data->line.end2[1];
edgepnt2[2] = p_data->data.p_curve_data->line.end2[2];
num2 = 1;
}
}
err = ProGeomitemdataFree(&p_data);
if (err != PRO_TK_NO_ERROR) return;
}