Beispiel #1
0
        /// <summary>
        /// 由点集计算平面法向量
        /// </summary>
        /// <param name="pts">点集</param>
        /// <returns></returns>
        public static bool CalcNormalVector(sg_Vector3[] pts, out sg_Vector3 n)
        {
            n = null;
            int iCount = pts.Length;

            if (iCount < 3)
            {
                return(false);
            }
            sg_Vector3 pt1 = pts[0];
            sg_Vector3 pt2 = null;

            for (int i = 1; i < iCount; i++)
            {
                pt2 = pts[i];
                if (sg_math.isZero(pt2.DistTo(pt1)))
                {
                    pt2 = null;
                }
                else
                {
                    break;
                }
            }
            if (pt2 == null)
            {
                return(false);
            }
            sg_Vector3 v1 = pt2 - pt1;
            sg_Vector3 v2 = null;

            for (int i = 1; i < iCount; i++)
            {
                var pt3 = pts[i];
                if (sg_math.isZero(pt3.DistTo(pt1)) ||
                    sg_math.isZero(pt3.DistTo(pt2)))
                {
                    pt3 = null;
                    continue;
                }
                v2 = pt3 - pt1;
                if (!v2.isParallel(v1))
                {
                    break;
                }
                v2 = null;
            }
            if (v2 == null)
            {
                return(false);
            }

            n = v1.crossMul(v2);
            // 如果与Z轴夹角大于90度 则反向
            if (n.getInterAngle(new sg_Vector3(0, 0, 1)) > 90)
            {
                n.reverse();
            }
            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// 像素坐标转成局部坐标
        /// </summary>
        /// <param name="p">像素坐标</param>
        /// <returns></returns>
        private sg_Vector3 Trans_XSToJB(Point p)
        {
            double     jBx = p.X * doc.recWidth / widthScreen;
            double     jBy = (p.Y - toolbar.Size.Height) * doc.recHeight / heightScreen;
            sg_Vector3 jB  = new sg_Vector3(jBx, jBy, 0);

            return(jB);
        }
Beispiel #3
0
 private void buttonXSave_Click(object sender, EventArgs e)
 {
     try
     {
         ctrlPtsKW         = new sg_Vector3(double.Parse(kwX.Text.ToString()), double.Parse(kwY.Text.ToString()), double.Parse(kwZ.Text.ToString()));
         this.DialogResult = DialogResult.OK;
     }
     catch
     {
         MessageBox.Show("数字格式不正确");
         return;
     }
 }
Beispiel #4
0
        /// <summary>
        /// 计算大地坐标系下的一个点,在当前开挖坐标系的中坐标
        /// </summary>
        /// <param name="coor">开挖坐标系</param>
        /// <param name="p">大地坐标系下的一个点</param>
        /// <returns></returns>
        public static sg_Vector3 ConverToThisSys(sg_Vector3[] coor, sg_Vector3 p)
        {
            sg_Vector3 sysX       = coor[1] - coor[0]; // 横坐标向量
            sg_Vector3 sysY       = coor[2] - coor[0]; //纵坐标向量
            sg_Vector3 _p         = p - coor[0];
            double     yDirection = sysX.x * sysY.y - sysY.x * sysX.y;


            double distance = Math.Sqrt(_p.x * _p.x + _p.y * _p.y);
            double fenMu    = Math.Sqrt(sysX.x * sysX.x + sysX.y * sysX.y) * Math.Sqrt(_p.x * _p.x + _p.y * _p.y);

            double fenZi1    = sysX.x * _p.x + sysX.y * _p.y;
            double cosValue1 = fenZi1 / fenMu;
            double xValue    = cosValue1 * distance;// 点的横坐标
            double yValue;
            double sinValue1 = Math.Sqrt(1 - cosValue1 * cosValue1);

            if (cosValue1 >= 0)
            {
                // 坐标系中的y轴如果与x轴是逆时针旋转后的成90度,则计算出的该点y坐标要乘-1
                if (sysX.x * _p.y - sysX.y * _p.x >= 0)
                {
                    yValue = sinValue1 * distance;
                }
                else
                {
                    yValue = -sinValue1 * distance;
                }
            }
            else
            {
                // 坐标系中的y轴如果与x轴是逆时针旋转后的成90度,则计算出的该点y坐标要乘-1
                if (-sysX.x * _p.y - -sysX.y * _p.x <= 0)
                {
                    yValue = sinValue1 * distance;
                }
                else
                {
                    yValue = -sinValue1 * distance;
                }
            }

            double yDirction = sysX.x * sysY.y - sysY.x * sysX.y;

            if (yDirction < 0)
            {
                yValue = -1 * yValue;
            }

            return(new sg_Vector3(xValue, yValue, _p.z));
        }
Beispiel #5
0
        /// <summary>
        /// 得到数据来源的局部编录坐标系 (还未实现)
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pts"></param>
        /// <returns></returns>
        public static bool get_JBBLZBPt3(string id, out sg_Vector3[] pts)
        {
            pts = new sg_Vector3[3];

            DataTable dt = BLHTBLL.GetXDMXJDZB(id);

            if (dt.Rows.Count == 0)
            {
                return(false);
            }

            // 待实现
            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="orgin">开挖坐标原点</param>
        /// <param name="H_Point">开挖坐标X(横)坐标轴上一点</param>
        /// <param name="V_Point">开挖坐标Y(纵)坐标轴正方向侧的任意点</param>
        public M1(sg_Vector3 orgin, sg_Vector3 H_Point, sg_Vector3 V_Point)
        {
            sg_Vector3 newZ = new sg_Vector3(0, 0, 1);
            sg_Vector3 newX = H_Point - orgin;

            sg_Vector3 YR1   = V_Point - orgin;
            sg_Vector3 newY  = newZ.crossMul(newX);
            double     angle = Math.Abs(YR1.getInterAngle(newY));// 两向量夹角

            if (angle > 90)
            {
                newY.reverse();
            }

            mTrans = new sg_Transformation(newZ, newX, newY, orgin);
        }
Beispiel #7
0
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="pt1">局部编录坐标控制点1</param>
        /// <param name="pt2">局部编录坐标控制点2</param>
        /// <param name="pt3">局部编录坐标控制点3</param>
        public M3(sg_Vector3 pt1, sg_Vector3 pt2, sg_Vector3 pt3, double xOffset = 0.0, double yOffset = 0.0)
        {
            ctrlPts    = new sg_Vector3[3];
            ctrlPts[0] = pt1;
            ctrlPts[1] = pt2;
            ctrlPts[2] = pt3;


            sg_Vector3 v12 = pt2 - pt1;
            sg_Vector3 v13 = pt3 - pt1;

            if (v12.isParallel(v13))
            {
            }
            else
            {
            }


            sg_Vector3 newZ = new sg_Vector3(0, 0, 1);
            sg_Vector3 newX = pt2 - pt1;

            sg_Vector3 YR1   = pt3 - pt1;
            sg_Vector3 newY  = newZ.crossMul(newX);
            double     angle = Math.Abs(YR1.getInterAngle(newY)); // 两向量夹角

            if (angle > 90)
            {
                newY.reverse();
            }


            sg_Vector3 nLocalXoY    = v12.crossMul(v13);       // 局部编录面法向量
            sg_Vector3 nGeodeticXoY = new sg_Vector3(0, 0, 1); // 大地坐标XoY面法向量
            sg_Vector3 nx           = nLocalXoY.isParallel(nGeodeticXoY)
                                ? new sg_Vector3(1, 0, 0)
                                : nLocalXoY.crossMul(nGeodeticXoY);
            sg_Vector3 ny = nLocalXoY.isParallel(nGeodeticXoY)
                                ? new sg_Vector3(0, 1, 0)
                                : nLocalXoY.crossMul(nx);
            sg_Vector3 nz = nx.crossMul(ny);

            sg_Vector3 origin = new sg_Vector3(pt1.x + xOffset, pt1.y + yOffset, pt1.z);

            this.mTrans = new sg_Transformation(nz, nx, ny, origin);
            IsValid     = true;
        }
Beispiel #8
0
        /// <summary>
        /// 判断点集是否共线
        /// </summary>
        /// <param name="pts">点集</param>
        /// <returns></returns>
        public static bool IsPtsCollinear(sg_Vector3[] pts)
        {
            int iCount = pts.Length;

            // 若点集中的点数小于3个,判定共线
            if (iCount < 3)
            {
                return(true);
            }

            // 获取第一个非零辅助向量
            sg_Vector3 v1 = pts[1] - pts[0];

            if (v1.isZero())
            {
                for (int i = 2; i < iCount; ++i)
                {
                    v1 = pts[i] - pts[0];
                    if (!v1.isZero())
                    {
                        break;
                    }
                }
            }

            // 获取第二个非零辅助向量
            for (int j = 1; j < iCount; ++j)
            {
                var v2 = pts[j] - pts[0];
                if (v2.isZero())
                {
                    continue;
                }

                // 若两个非零辅助向量不平行,则判定不共线
                if (!v1.isParallel(v2))
                {
                    return(false);
                }
            }

            // 若两个非零辅助向量始终平行,则判定共线
            return(true);
        }
Beispiel #9
0
        /// <summary>
        /// 得到数据来源的局部编录坐标系 (还未实现)
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pts"></param>
        /// <returns></returns>
        public static bool get_JBBLZBPt3(string id, IGPoint[] slopePts, out sg_Vector3[] pts)
        {
            //边坡的 3 个点
            sg_Vector3[] slopeCtrl = new sg_Vector3[3];
            sg_Vector3[] sysPts    = new sg_Vector3[3];
            pts = new sg_Vector3[3];
            get_KWZBPt3(id, out sysPts);  //获取 开挖坐标的三个点

            //sg_Vector3 sysX = sysPts[1] - sysPts[0]; // 横坐标向量
            //sg_Vector3 sysY = sysPts[2] - sysPts[0];//纵坐标向量

            //判断 y 轴与 x 轴的相对位置
            //double yDirection = sysX.x * sysY.y - sysY.x * sysX.y;


            for (int i = 0; i < 3; i++)
            {
                slopeCtrl[i] = new sg_Vector3(slopePts[i].X, slopePts[i].Y, slopePts[i].Z);
                pts[i]       = ConverToThisSys(sysPts, slopeCtrl[i]);
            }

            return(true);
        }
Beispiel #10
0
 private void buttonXSave_Click(object sender, EventArgs e)
 {
     if (chooseCtrlPts.Text == "控制点1")
     {
         ctrlPtsKW    = new sg_Vector3(pKWInThis[0].x, pKWInThis[0].y, pKWInThis[0].z);
         DialogResult = DialogResult.OK;
     }
     else if (chooseCtrlPts.Text == "控制点2")
     {
         ctrlPtsKW    = new sg_Vector3(pKWInThis[1].x, pKWInThis[1].y, pKWInThis[1].z);
         DialogResult = DialogResult.OK;
     }
     else if (chooseCtrlPts.Text == "控制点3")
     {
         ctrlPtsKW    = new sg_Vector3(pKWInThis[2].x, pKWInThis[2].y, pKWInThis[2].z);
         DialogResult = DialogResult.OK;
     }
     else
     {
         MessageBox.Show("请选择控制点");
         return;
     }
 }
Beispiel #11
0
        /// <summary>
        /// 得到数据来源的开挖坐标系
        /// </summary>
        /// <param name="id">数据来源ID</param>
        /// <param name="pts"></param>
        /// <returns></returns>
        public static bool get_KWZBPt3(string id, out sg_Vector3[] pts)
        {
            // 坐标系ID
            pts = new sg_Vector3[3];

            string zbxtid = ColumnType.ConvertStringNotDBNull(BaseBll.GetSingleValue(
                                                                  $"SELECT ZBXTID FROM SJLYK WHERE ID='{id}'"));

            if (string.IsNullOrEmpty(zbxtid))
            {
                //没有坐标系不计算
                return(false);
            }
            //获取坐标系的控制控制点坐标  //cl 2016/09/21 这里应是获取开挖坐标系
            DataSet ds = GCKWZBXTKBLL.GetKZDZBByZTXTID(zbxtid);

            if (ds.Tables[GCKWZBXTKModel.TableName].Rows.Count == 0)
            {
                //没有坐标系不计算
                return(false);
            }
            string ydid = ds.Tables[GCKWZBXTKModel.TableName].Rows[0][GCKWZBXTKModel.YDID].ToString();

            //if (!string.IsNullOrEmpty(ydid))
            //{
            if (string.IsNullOrEmpty(ydid))//修改 xyb,为什么是有值还不计算?
            {
                //没有原点坐标,不计算
                return(false);
            }
            string hzbid = ds.Tables[GCKWZBXTKModel.TableName].Rows[0][GCKWZBXTKModel.HZBID].ToString();

            if (string.IsNullOrEmpty(hzbid))
            {
                //没有x方向坐标,不计算
                return(false);
            }
            string zzbid = ds.Tables[GCKWZBXTKModel.TableName].Rows[0][GCKWZBXTKModel.ZZBID].ToString();

            if (string.IsNullOrEmpty(zzbid))
            {
                //没有y方向坐标,不计算
                return(false);
            }

            //开挖坐标系原点坐标
            DataRow drYD = ds.Tables[GCKZDZBKModel.TableName].Rows.Find(ydid);
            double  x    = double.Parse(drYD["X"].ToString());
            double  y    = double.Parse(drYD["Y"].ToString());
            double  z    = double.Parse(drYD["Z"].ToString());

            pts[0] = new sg_Vector3(x, y, z);

            //开挖坐标系X坐标
            DataRow hdr = ds.Tables[GCKZDZBKModel.TableName].Rows.Find(hzbid);

            x      = double.Parse(hdr["X"].ToString());
            y      = double.Parse(hdr["Y"].ToString());
            z      = double.Parse(hdr["Z"].ToString());
            pts[1] = new sg_Vector3(x, y, z);

            //开挖坐标系Y坐标
            DataRow zdr = ds.Tables[GCKZDZBKModel.TableName].Rows.Find(zzbid);

            x      = double.Parse(zdr["X"].ToString());
            y      = double.Parse(zdr["Y"].ToString());
            z      = double.Parse(zdr["Z"].ToString());
            pts[2] = new sg_Vector3(x, y, z);

            return(true);
        }
Beispiel #12
0
 /// <summary>
 /// 由点集计算平面法向量 //???
 /// </summary>
 /// <returns></returns>
 private bool CalcNormalVector(sg_Vector3[] pts)
 {
     NormalVector = new sg_Vector3(0, 0, 0);
     return(true);
 }
Beispiel #13
0
        /// <summary>
        /// 设定初始数据
        /// </summary>
        private void Init()
        {
            // 获取地质对象的三个控制点,若找不到控制点,则退出
            sg_Vector3[] ptsForM1;
            if (!CoordSys.CoordHelp.get_KWZBPt3(SJLYID, out ptsForM1))
            {
                return;
            }

            // 根据三个控制点,建立M1
            if (ptsForM1.Count() > 2)
            {
                m1 = new CoordSys.M1(ptsForM1);
            }

            string DXID      = string.Empty;
            string OperateID = GUIDGenerator.NewGUID;

            EditDataSet = GLDXMDXKBLL.GetEditDataSet(SJLYID, OperateID, DXID, string.Empty); // ?

            sg_Vector3[] ptsForM3;                                                           // 用于求M3的控制点
            dt = BLHTBLL.GetXDMXJDZB(SJLYID);                                                // 用于求M3(可能重构进入CoordHelp相关函数中)

            if (!CoordHelp.get_JBBLZBPt3(SJLYID, out ptsForM3))
            {
                return;
            }

            // 根据三个控制点,建立M3
            if (!CoordHelp.IsPtsCollinear(ptsForM3))
            {
                this.m3Raw = new M3(ptsForM3);
            }

            if (!this.m3Raw.IsValid)
            {
                throw new Exception("M3创建失败,请检查控制点坐标。");
            }

            // 大地控制点在M3下的坐标
            sg_Vector3 pts1InM3 = this.m3Raw.getLocCoord(ptsForM3[0]);
            sg_Vector3 pts2InM3 = this.m3Raw.getLocCoord(ptsForM3[1]);
            sg_Vector3 pts3InM3 = this.m3Raw.getLocCoord(ptsForM3[2]);

            // 获取新的原点
            double xNewO = Math.Min(Math.Min(pts1InM3.x, pts2InM3.x), pts3InM3.x);
            double yNewO = Math.Min(Math.Min(pts1InM3.y, pts2InM3.y), pts3InM3.y);


            // 获取新原点下的坐标偏移值
            double xOffset = xNewO - pts1InM3.x;  // 减控制点1的横纵坐标什么意思???
            double yOffset = yNewO - pts1InM3.y;

            // 建立M3Screen (M3与M3Screen)
            this.m3Screen = new M3(ptsForM3, xOffset, yOffset);

            // 确定矩形参数 //矩形的四个顶点作为屏幕坐标的基准点
            recWidth = Math.Max(Math.Max(pts1InM3.x, pts2InM3.x), pts3InM3.x)
                       - Math.Min(Math.Min(pts1InM3.x, pts2InM3.x), pts3InM3.x);
            recHeight = Math.Max(Math.Max(pts1InM3.y, pts2InM3.y), pts3InM3.y)
                        - Math.Min(Math.Min(pts1InM3.y, pts2InM3.y), pts3InM3.y);
            sg_Vector3 recLeftLow   = new sg_Vector3(0, 0);
            sg_Vector3 recLeftHigh  = new sg_Vector3(0, recHeight);
            sg_Vector3 recRightLow  = new sg_Vector3(recWidth, 0);
            sg_Vector3 recRightHigh = new sg_Vector3(recWidth, recHeight);

            widthHeightRito = recWidth / recHeight;

            // 绘制矩形
        }
Beispiel #14
0
 /// <summary>
 /// 由局部编录坐标计算大地坐标
 /// </summary>
 /// <param name="pt">以局部编录坐标表示的点</param>
 /// <returns></returns>
 public sg_Vector3 getWorldCoord(sg_Vector3 pt)
 {
     return(mTrans.apply(pt));
 }
Beispiel #15
0
 /// <summary>
 /// 由大地坐标计算局部编录坐标
 /// </summary>
 /// <param name="pt">以大地坐标表示的点</param>
 /// <returns></returns>
 public sg_Vector3 getLocCoord(sg_Vector3 pt)
 {
     return(mTrans.inverse(pt));
 }