首页 / 浏览问题 / 组件GIS / 问题详情
如何根据一个点取指定偏移距离三维线上的下一个点
66EXP 2017年05月04日
已经画好一条三维线GeoLine3D,在线上取一点P1,如何取距离P1指定距离的线上下一点P2? 用组件开发如何实现?能提供示例代码最好.

2 个回答

您好,如果您的三维线是多节点的话,您也可以参考下这个: 

private GeoPoint3D nextPoint3D(GeoLine3D geoLine3D, GeoPoint3D startPoint3D, double distance)
        {
            //geoLine3D:三维线
            Point3Ds point3Ds = geoLine3D[0];
            //p1:起始点
            GeoPoint3D p1 = startPoint3D;
            //requestDistance:经过距离
            double requestDistance = distance;

            double distance1 = 0;
            int startPointPosition = 0;

            //检查p1在三维线上的具体位置
            for(int i = 1; i < point3Ds.Count; i++)
            {
                GeoPoint3D geoPoint3DStart = new GeoPoint3D(point3Ds[i - 1]);
                GeoPoint3D geoPoint3DEnd = new GeoPoint3D(point3Ds[i]);
                if (Geometrist.Distance(p1, geoPoint3DStart) + Geometrist.Distance(p1, geoPoint3DEnd) == Geometrist.Distance(geoPoint3DStart, geoPoint3DEnd))
                {
                    distance1 = Geometrist.Distance(p1, geoPoint3DStart);
                    break;
                }else
                {
                    startPointPosition=i;
                }
            }
            //p1不在三维线上,返回null
            if(startPointPosition == point3Ds.Count - 1)
            {
                MessageBox.Show("start point not at given line!");
                return null;
            }
            //计算结果点
            requestDistance = requestDistance + distance1;
            for (int i = startPointPosition+1; i < point3Ds.Count; i++)
            {
                GeoPoint3D geoPoint3DStart = new GeoPoint3D(point3Ds[i - 1]);
                GeoPoint3D geoPoint3DEnd = new GeoPoint3D(point3Ds[i]);
                requestDistance = requestDistance - Geometrist.Distance(geoPoint3DStart, geoPoint3DEnd);
                if (requestDistance<0)
                {
                    double requestDistanceRate = Math.Abs(requestDistance) / Geometrist.Distance(geoPoint3DStart, geoPoint3DEnd);
                    double x2 = geoPoint3DEnd.X - (geoPoint3DEnd.X - geoPoint3DStart.X) * requestDistanceRate;
                    double y2 = geoPoint3DEnd.Y - (geoPoint3DEnd.Y - geoPoint3DStart.Y) * requestDistanceRate;
                    double z2 = geoPoint3DEnd.Z - (geoPoint3DEnd.Z - geoPoint3DStart.Z) * requestDistanceRate;
                    GeoPoint3D p2 = new GeoPoint3D(x2, y2, z2);
                    return p2;
                }
            }
            //距离超出线的长度,返回null
            MessageBox.Show("Out of range!");
            return null;
        }

5,560EXP 2017年05月04日
非常感谢,你非常理解我的需求.像这些常用的点线关系超图组件如果封装成一个通用类或方法,方便我们这些二次开发人员直接调用就更好了.
Geometrist.Distance(p1,p2)这个方法返回的单位是什么?为什么我调试发现这个方法返回一直是0?

坐标系是经纬度的,如何返回两点间的距离为米? 要用这个方法ComputeGeodesicDistance吗? 可是这个是二维的.

哦哦忘记了,这个geometrist不支持三维的。

        private double distance3D(GeoPoint3D p1, GeoPoint3D p2)
        {
            return Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) +
                (p1.Y - p2.Y) * (p1.Y - p2.Y) +
                (p1.Z - p2.Z) * (p1.Z - p2.Z));
        }

然后您把所有的Geometrist.Distance都换成distance3D就可以了。

经纬度坐标系的话,您需要先将经纬度坐标系转换成投影坐标系(XY坐标系)。

地理坐标系转投影坐标系:CoordSysTranslator.Convert(Dataset, PrjCoordSys, CoordSysTransParameter, CoordSysTransMethod)
非常感谢.

您好,请参考:

/// <summary>
        /// 到终点指定距离求三维线上一点
        /// </summary>
        /// <param name="startPoint3D">起始点</param>
        /// <param name="endPoint3D">终止点</param>
        /// <param name="distance">距离</param>
        /// <returns></returns>
        private Point3D GetPoint3DByDistance(Point3D startPoint3D, Point3D endPoint3D, double distance)
        {
            Point3D reslutPoint3D = new Point3D();
            //起始点和终止点之间的距离
            double distanceAB = Math.Sqrt((startPoint3D.X - endPoint3D.X) * (startPoint3D.X - endPoint3D.X) + (startPoint3D.Y - endPoint3D.Y) * (startPoint3D.Y - endPoint3D.Y) + (startPoint3D.Z - endPoint3D.Z) * (startPoint3D.Z - endPoint3D.Z));
            distance = distanceAB / 4.0;
            Distance = distance;
            //得到返回点的XYZ值
            double Z = 0;
            double X = 0;
            double Y = 0;
            if (startPoint3D.Z == endPoint3D.Z)
            {
                Z = startPoint3D.Z;
                double Yone = Math.Sqrt(1 / ((startPoint3D.X - endPoint3D.X) * (startPoint3D.X - endPoint3D.X) + (startPoint3D.Y - endPoint3D.Y) * (startPoint3D.Y - endPoint3D.Y)) * distance * Math.Abs(startPoint3D.Y - endPoint3D.Y)) + endPoint3D.Y;
                double Ytwo = -Math.Sqrt(1 / ((startPoint3D.X - endPoint3D.X) * (startPoint3D.X - endPoint3D.X) + (startPoint3D.Y - endPoint3D.Y) * (startPoint3D.Y - endPoint3D.Y)) * distance * Math.Abs(startPoint3D.Y - endPoint3D.Y)) + endPoint3D.Y;
                double Xone = Math.Sqrt(1 / ((startPoint3D.X - endPoint3D.X) * (startPoint3D.X - endPoint3D.X) + (startPoint3D.Y - endPoint3D.Y) * (startPoint3D.Y - endPoint3D.Y)) * distance * Math.Abs(startPoint3D.X - endPoint3D.X)) + endPoint3D.X;
                double Xtwo = -Math.Sqrt(1 / ((startPoint3D.X - endPoint3D.X) * (startPoint3D.X - endPoint3D.X) + (startPoint3D.Y - endPoint3D.Y) * (startPoint3D.Y - endPoint3D.Y)) * distance * Math.Abs(startPoint3D.X - endPoint3D.X)) + endPoint3D.X;
                if ((Yone < startPoint3D.Y && Yone > endPoint3D.Y) || (Yone > startPoint3D.Y && Yone < endPoint3D.Y))
                {
                    Y = Yone;
                }
                else
                {
                    Y = Ytwo;
                }
                if ((Xone < startPoint3D.X && Xone > endPoint3D.X) || (Xone > startPoint3D.X && Xone < endPoint3D.X))
                {
                    X = Xone;
                }
                else
                {
                    X = Xtwo;
                }
            }
            else
            {
                double Zone = (distance / distanceAB) * Math.Abs(startPoint3D.Z - endPoint3D.Z) + endPoint3D.Z;
                double Ztwo = -(distance / distanceAB) * Math.Abs(startPoint3D.Z - endPoint3D.Z) + endPoint3D.Z;
                if ((Zone < startPoint3D.Z && Zone > endPoint3D.Z) || (Zone > startPoint3D.Z && Zone < endPoint3D.Z))
                {
                    Z = Zone;
                }
                else
                {
                    Z = Ztwo;
                }
                X = (endPoint3D.X - startPoint3D.X) * (Z - startPoint3D.Z) / (endPoint3D.Z - startPoint3D.Z) + startPoint3D.X;
                Y = (endPoint3D.Y - startPoint3D.Y) * (Z - startPoint3D.Z) / (endPoint3D.Z - startPoint3D.Z) + startPoint3D.Y;               
            }
            reslutPoint3D.X = X;
            reslutPoint3D.Y = Y;
            reslutPoint3D.Z = Z;
            return reslutPoint3D;
        }

3,389EXP 2017年05月04日
你这个方法应该是假定线是直线才可以,也是非常感谢你提供的代码.
对哈,您根据需求扩展一下呢。
...