[MSCE C#]CurveLocationDetail的fraction总是得不到正确结果

老师您好:我使用 CurveLocationDetail 时有两个问题:

1) curveLocationDetail = curveVector.ClosestPointBoundedXY(spacePt);这个函数来计算一个点在线串上的位置,如下图,这是一个线串,我选中的是1/3处的点,但是算出来的fraction总是不对,这里显示的是0.5,实际上我理解应该是0.33,因为这是1/3处,我测试了spacePt和的出来的Point都是正确的,这里spacePt在线串上,所以等于Point,我测试了其他的线串还是算不对,想请教一下这个应该怎么用?

这里这个线串是在XOY平面的

2)CurveLocationDetail curveLocationDetail2 = curveVector.ClosestPointBounded(spacePt); 当我用ClosestPointBounded这个函数的时候,结果一直为null

  • 看不到您的图示。不过我写代码对单段直线和多段线串测试了ClosestPointBoundedXY,得到的Fraction值均是正确的。

    是否你给spacePt点时工作单位不正确?这个一定要用UOR单位而不能用主单位!!!



  • 符老师您好:我试了很多,仍然得不到正确结果,不过有些规律,对于单线段,结果总是对的,对于多段线串,我选在某条线段的终点进行测试,得到的结果总是=curveLocationDetail.ComponentIndex/curveLocationDetail.NumberComponent; 如果选择某条线段的中点进行测试,得到的结果就是:到当前位置的半线段个数/(总个数*2),因此我觉得我得到的结果总是按照线段个数来分,而不是按照长度,我不知道哪里出了错,附件中,我将测试用的代码和dgn文件都附上了,请老师帮我看看,麻烦您了Addin.rar

  • 我用您的DGN套入我写的一段测试代码如下。结果是正确的。注意,不需要分门别类地取得元素后调用GetCurveVector得到对应的CurveVector,可以直接用CurvePathQuery.ElementToCurveVector从符合要求的元素(2D线性元素)直接得到对应的CurveVector。

    DgnModel dgnModel = Session.Instance.GetActiveDgnModel();
    Element myElem = dgnModel.FindElementById((ElementId)784L);
    CurveVector cv = CurvePathQuery.ElementToCurveVector(myElem);
    CurveLocationDetail cld = cv.ClosestPointBoundedXY(DPoint3d.FromXYZ(166770, -52570, 0));
    System.Windows.Forms.MessageBox.Show(cld.Fraction.ToString());



    Answer Verified By: nadine z 

  • 符老师,如果我用这个结果求沿着线串从起点到该投影点的距离,我理解应该是fraction*线串的总长度,即0.2*32.265 = 6.453,但是实际测出来从起点到该点的距离是9.975,是不是我对这个fraction理解有误?

  • 是的。您对fraction的含义理解有误。对于LineString,这个fraction的含义是:

    起点的fraction为0,终点的fraction为1,中间各顶点的fraction为1/N, 2/N, 3/N...以此类推(N为LineString的段数)。对于每段中间的点,其fraction值如下(componentFraction是本段中的fraction)。如下测试图可明白一些:

    如果想计算按实际长度得到的distFraction,可按如下代码编写:

                DgnModel dgnModel = Session.Instance.GetActiveDgnModel();
                Element myElem = dgnModel.FindElementById((ElementId)784L);
                CurveVector cv = CurvePathQuery.ElementToCurveVector(myElem);
                CurveLocationDetail cld = cv.ClosestPointBoundedXY(DPoint3d.FromXYZ(121690, -73910, 0));
                double dist, totalDist;
                cv.GetPrimitive(0).SignedDistanceBetweenFractions(0, cld.Fraction, out dist);
                cv.GetPrimitive(0).SignedDistanceBetweenFractions(0, 1, out totalDist);
                System.Windows.Forms.MessageBox.Show("distFraction=" + dist/totalDist);



    Answer Verified By: nadine z