Exemplo n.º 1
0
        /// <summary>
        /// 获取线状要素
        /// </summary>
        /// <param name="pDataRecords">数据记录</param>
        /// <param name="dblProp">插值参数</param>
        /// <returns>在处理面状要素时,本程序将原面状要素的边界切开,按线状要素处理,处理完后再重新生成面状要素</returns>
        public CPolyline GetTargetcpl(double dblProp, CPolyline lastcpl)
        {
            if (dblProp == 0)
            {
                int aa = 5;
            }

            List <CCorrCpts> pCorrCptsLt = _DataRecords.ParameterResult.CCorrCptsLt;   //读取数据后,此处ResultPtLt中的对应点为一一对应
            double           dblTX       = _dblTX;

            int intPtNum = pCorrCptsLt.Count;
            int intXYNum = 2 * intPtNum;

            //计算长度初始值(全部计算)
            double[] adblLength0   = new double[intPtNum - 1];
            double[] adblFrLength0 = new double[intPtNum - 1];
            double[] adblToLength0 = new double[intPtNum - 1];
            for (int i = 0; i < pCorrCptsLt.Count - 1; i++)
            {
                double dblfrsublength = CGeoFunc.CalDis(pCorrCptsLt[i + 1].FrCpt, pCorrCptsLt[i].FrCpt);
                adblFrLength0[i] = dblfrsublength;
                double dbltosublength = CGeoFunc.CalDis(pCorrCptsLt[i + 1].ToCpt, pCorrCptsLt[i].ToCpt);
                adblToLength0[i] = dbltosublength;
                adblLength0[i]   = (1 - dblProp) * dblfrsublength + dblProp * dbltosublength;
            }

            //计算角度初始值(全部计算)
            double[] adblAngle0 = new double[intPtNum - 2];
            for (int i = 0; i < pCorrCptsLt.Count - 2; i++)
            {
                //较大比例尺线状要素上的夹角
                double dblfrAngle = CGeoFunc.CalAngle_Counterclockwise(pCorrCptsLt[i].FrCpt, pCorrCptsLt[i + 1].FrCpt, pCorrCptsLt[i + 2].FrCpt);
                //较小比例尺线状要素上的夹角
                double dbltoAngle = CGeoFunc.CalAngle_Counterclockwise(pCorrCptsLt[i].ToCpt, pCorrCptsLt[i + 1].ToCpt, pCorrCptsLt[i + 2].ToCpt);

                //角度初始值
                adblAngle0[i] = (1 - dblProp) * dblfrAngle + dblProp * dbltoAngle;
            }

            //计算坐标初始值,以及各线段方位角初始值
            //注意:默认固定第一条边
            pCorrCptsLt[0].FrCpt.isCtrl = true;
            pCorrCptsLt[1].FrCpt.isCtrl = true;
            //固定最后两条边
            pCorrCptsLt[intPtNum - 1].FrCpt.isCtrl = true;
            pCorrCptsLt[intPtNum - 2].FrCpt.isCtrl = true;

            VBMatrix X0 = new VBMatrix(intXYNum, 1);

            //以上一次结果的值作为新的估算值
            List <CPoint> lastcptlt = lastcpl.CptLt;

            for (int i = 0; i < intPtNum; i++)
            {
                if (pCorrCptsLt[i].FrCpt.isCtrl == false)
                {
                    X0[2 * i + 0, 0] = lastcptlt[i].X;
                    X0[2 * i + 1, 0] = lastcptlt[i].Y;
                }
                else
                {
                    X0[2 * i + 0, 0] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.X + dblProp * pCorrCptsLt[i].ToCpt.X;
                    X0[2 * i + 1, 0] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.Y + dblProp * pCorrCptsLt[i].ToCpt.Y;
                }
            }

            //统计插值点数
            int intKnownPt   = 0;                             //固定点的数目
            int intUnknownPt = 0;                             //非固定点的数目

            List <int> intKnownLocationLt = new List <int>(); //记录已知点的序号

            //注意:对于该循环,有一个默认条件,即FromCpl的第一个顶点只有一个对应点
            for (int i = 0; i < pCorrCptsLt.Count; i++)
            {
                if (pCorrCptsLt[i].FrCpt.isCtrl == true)
                {
                    intKnownLocationLt.Add(i);
                    intKnownPt += 1;
                }
                else
                {
                    intUnknownPt += 1;
                }
            }
            int intUnknownXY = intUnknownPt * 2;   //每个点都有X、Y坐标

            //找出长度固定的位置(如果一个线段的前后两个点都固定,则该长度固定)。另外,长度固定则该边的方位角也固定
            List <int> intKnownLengthLt = new List <int>();

            for (int i = 0; i < intKnownLocationLt.Count - 1; i++)
            {
                if ((intKnownLocationLt[i + 1] - intKnownLocationLt[i]) == 1)
                {
                    intKnownLengthLt.Add(intKnownLocationLt[i]);
                }
            }
            int intUnknownLength = intPtNum - 1 - intKnownLengthLt.Count;

            //找出角度固定的位置(如果一个固定顶点的前后两个点都固定,则该角度固定)
            List <int> intKnownAngleLt = new List <int>();

            for (int i = 0; i < intKnownLocationLt.Count - 2; i++)
            {
                if ((intKnownLocationLt[i + 1] - intKnownLocationLt[i]) == 1 && (intKnownLocationLt[i + 2] - intKnownLocationLt[i + 1]) == 1)
                {
                    intKnownAngleLt.Add(intKnownLocationLt[i]);
                }
            }
            int intUnknownAngle = intPtNum - 2 - intKnownAngleLt.Count;

            //长度及角度未知量(方便使用)
            int intUnknownLengthAngle = intUnknownLength + intUnknownAngle;
            //总未知量
            int intUnknownLengthAnglePt = intUnknownLength + intUnknownAngle + intUnknownPt;

            //定义权重矩阵
            int      intKnownCount   = 0;
            int      intUnKnownCount = 0;
            VBMatrix P = new VBMatrix(intUnknownLengthAnglePt, intUnknownLengthAnglePt);

            for (int i = 0; i < intUnknownLength; i++)
            {
                P[i, i] = 1;
            }
            for (int i = 0; i < intUnknownAngle; i++)
            {
                int intSumCount = intKnownCount + intUnKnownCount;

                //开始计算系数值,由于将以下三个情况排列组合将有八种情况,因此按如下方式计算
                if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 2].FrCpt.isCtrl == true)
                {
                    i -= 1;
                }
                else
                {
                    double dblWeight = 0;
                    if (pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == false)
                    {
                        dblWeight = adblFrLength0[intSumCount] + adblFrLength0[intSumCount + 1] + adblToLength0[intSumCount] + adblToLength0[intSumCount + 1];
                    }
                    else if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == false && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 2].FrCpt.isCtrl == false)
                    {
                        dblWeight = adblFrLength0[intSumCount] + adblFrLength0[intSumCount + 1] + adblToLength0[intSumCount] + adblToLength0[intSumCount + 1];
                    }
                    else if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 2].FrCpt.isCtrl == false)
                    {
                        dblWeight = adblFrLength0[intSumCount + 1] + adblToLength0[intSumCount + 1];
                    }
                    else if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == false && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 2].FrCpt.isCtrl == true)
                    {
                        dblWeight = adblFrLength0[intSumCount] + adblToLength0[intSumCount];
                    }

                    P[intUnknownLength + i, intUnknownLength + i] = dblWeight;
                }

                if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == true)
                {
                    intKnownCount += 1;
                }
                else
                {
                    intUnKnownCount += 1;
                }
            }
            for (int i = 0; i < intUnknownPt; i++)
            {
                P[intUnknownLengthAngle + i, intUnknownLengthAngle + i] = 0.000000000000001;
            }

            //定义坐标近似值矩阵XA
            VBMatrix XA           = new VBMatrix(intUnknownXY, 1);
            VBMatrix XA0          = new VBMatrix(intUnknownXY, 1);
            int      intSumCount0 = 0;

            for (int i = 0; i < intUnknownPt; i++)
            {
                if (pCorrCptsLt[intSumCount0].FrCpt.isCtrl == false)
                {
                    XA0[i * 2 + 0, 0] = X0[intSumCount0 * 2 + 0, 0];
                    XA0[i * 2 + 1, 0] = X0[intSumCount0 * 2 + 1, 0];

                    XA[i * 2 + 0, 0] = XA0[i * 2 + 0, 0] - 0.0000000001;
                    XA[i * 2 + 1, 0] = XA0[i * 2 + 1, 0] - 0.0000000001;
                }
                else
                {
                    i -= 1;
                }
                intSumCount0 += 1;
            }

            //Xmix里存储了XA和X0的最新混合值(此矩阵在公式推导中并不存在,只是为了方便编写代码而建立)
            VBMatrix Xmix = new VBMatrix(intXYNum, 1);

            for (int i = 0; i < intXYNum; i++)
            {
                Xmix[i, 0] = X0[i, 0];
            }

            //近似值与观测值之差matl,平差中的-l
            VBMatrix matl = new VBMatrix(intUnknownLengthAnglePt, 1);

            //定义系数矩阵A(各方程对坐标的导数值),A的导数值将在循环中给出
            VBMatrix A                 = new VBMatrix(intUnknownLengthAnglePt, intUnknownXY);
            double   dblJudge1         = 0; //该值用于判断是否应该跳出循环
            double   dblJudge2         = 0; //该值用于判断是否应该跳出循环
            int      intJudgeIndex     = intUnknownLength / 4;
            int      intIterativeCount = 0;

            double[] adblSubDis  = new double[intPtNum - 1];
            double[] adblAngle   = new double[intPtNum - 2];
            double[] adblAzimuth = new double[intPtNum - 1];
            do
            {
                //计算系数矩阵A第0行到"intUnknownLength"行的各元素,即线段长度对各未知数求偏导的值
                for (int i = 0; i < intPtNum - 1; i++)
                {
                    adblSubDis[i] = Math.Pow((Xmix[2 * i, 0] - Xmix[2 * i + 2, 0]) * (Xmix[2 * i, 0] - Xmix[2 * i + 2, 0]) + (Xmix[2 * i + 1, 0] - Xmix[2 * i + 3, 0]) * (Xmix[2 * i + 1, 0] - Xmix[2 * i + 3, 0]), 0.5);
                }
                //计算新的方位角
                adblAzimuth[0] = CGeoFunc.CalAxisAngle(Xmix[0, 0], Xmix[1, 0], Xmix[2, 0], Xmix[3, 0]);
                for (int i = 1; i < intPtNum - 1; i++)
                {
                    adblAngle[i - 1] = CGeoFunc.CalAngle_Counterclockwise(Xmix[i * 2 - 2, 0], Xmix[i * 2 - 1, 0], Xmix[i * 2, 0], Xmix[i * 2 + 1, 0], Xmix[i * 2 + 2, 0], Xmix[i * 2 + 3, 0]);
                    adblAzimuth[i]   = adblAzimuth[i - 1] + adblAngle[i - 1] - Math.PI;
                }

                //计算系数矩阵中关于长度值的导数部分
                _pCAL.CalADevLength(pCorrCptsLt, 0, intUnknownLength, ref A, ref matl, adblSubDis, adblAzimuth, adblLength0);

                //计算系数矩阵中关于夹角值的导数部分
                _pCAL.CalADevAngle(pCorrCptsLt, intUnknownLength, intUnknownAngle, Xmix, ref A, ref matl, adblSubDis, adblAngle, adblAngle0);

                //计算系数矩阵中关于与上一个LSA结果坐标距离的导数部分
                for (int i = 0; i < intUnknownPt; i++)
                {
                    //平差后的点与估计值点之间的距离
                    double dblDis = Math.Pow((XA[2 * i, 0] - XA0[2 * i, 0]) * (XA[2 * i, 0] - XA0[2 * i, 0]) + (XA[2 * i + 1, 0] - XA0[2 * i + 1, 0]) * (XA[2 * i + 1, 0] - XA0[2 * i + 1, 0]), 0.5);

                    A[intUnknownLengthAngle + i, i * 2 + 0] = (XA[2 * i + 0, 0] - XA0[2 * i + 0, 0]) / dblDis;
                    A[intUnknownLengthAngle + i, i * 2 + 1] = (XA[2 * i + 1, 0] - XA0[2 * i + 1, 0]) / dblDis;

                    //if (dblDis==0)
                    //{
                    //    //导数值
                    //    A[intUnknownLengthAngle + i, i * 2 + 0] = 0;
                    //    A[intUnknownLengthAngle + i, i * 2 + 1] = 0;
                    //}
                    //else
                    //{
                    //    //导数值
                    //    A[intUnknownLengthAngle + i, i * 2 + 0] = (XA[2 * i + 0, 0] - XA0[2 * i + 0, 0]) / dblDis;
                    //    A[intUnknownLengthAngle + i, i * 2 + 1] = (XA[2 * i + 1, 0] - XA0[2 * i + 1, 0]) / dblDis;
                    //}

                    matl[intUnknownLengthAngle + i, 0] = -dblDis;    //图方便,顺便计算matl
                }

                //CHelpFuncExcel.ExportDataToExcel2(A, "maxA", _DataRecords.ParameterInitialize.strSavePath);
                //CHelpFuncExcel.ExportDataToExcelP(P, "maxP", _DataRecords.ParameterInitialize.strSavePath);
                //CHelpFuncExcel.ExportDataToExcel2(matl, "maxmatl", _DataRecords.ParameterInitialize.strSavePath);


                //平差(阻尼最小二乘法)
                VBMatrix Temp = A.Trans() * P * A;
                //VBMatrix E = new VBMatrix(intUnknownXY, intUnknownXY);  //单位矩阵
                //for (int i = 0; i < intUnknownXY; i++)
                //{
                //    E[i, i] = 1;
                //}
                //Temp = Temp + E;
                VBMatrix InvTemp = Temp.Inv(Temp);
                VBMatrix x       = InvTemp * A.Trans() * P * matl;

                //CHelpFuncExcel.ExportDataToExcel2(x, "maxX", _DataRecords.ParameterInitialize.strSavePath);
                //CHelpFuncExcel.ExportDataToExcel2(XA, "maxXA", _DataRecords.ParameterInitialize.strSavePath);

                XA += x;

                //对坐标值进行改正
                int intSumCount5 = 0;
                for (int i = 0; i < intUnknownPt; i++)
                {
                    if (pCorrCptsLt[intSumCount5].FrCpt.isCtrl == false)
                    {
                        Xmix[intSumCount5 * 2 + 0, 0] = XA[i * 2 + 0, 0];
                        Xmix[intSumCount5 * 2 + 1, 0] = XA[i * 2 + 1, 0];
                    }
                    else
                    {
                        i -= 1;
                    }
                    intSumCount5 += 1;
                }

                if (intIterativeCount == 50)
                {
                    int kk = 5;
                }

                intIterativeCount += 1;


                if (intIterativeCount >= 20)
                {
                    break;
                }

                //这里只是随便取两个中间值以观测是否收敛
                dblJudge1 = Math.Abs(x[intJudgeIndex, 0]);
                dblJudge2 = Math.Abs(x[3 * intJudgeIndex, 0]);
            } while ((dblJudge1 > dblTX) || (dblJudge2 > dblTX));


            //生成目标线段
            List <CPoint> CTargetPtLt = new List <CPoint>();

            for (int i = 0; i < intPtNum; i++)
            {
                CPoint cpt = new CPoint(i);
                cpt.X = Xmix[2 * i, 0];
                cpt.Y = Xmix[2 * i + 1, 0];

                if (pCorrCptsLt[i].FrCpt.isCtrl == true)
                {
                    cpt.isCtrl = true;
                }
                else
                {
                    cpt.isCtrl = false;
                }

                CTargetPtLt.Add(cpt);
            }
            CPolyline cpl = new CPolyline(0, CTargetPtLt);

            cpl.CreateSubPllt();

            //记录各平差成果
            //坐标改正值
            VBMatrix Xc = XA - XA0;
            //观测值改正值矩阵V
            VBMatrix V = A * Xc + matl;

            //VtPV值
            cpl.dblVtPV = (V.Trans() * P * V).MatData[0, 0];


            int intUnKnownCountL6 = 0;

            for (int i = 0; i < intPtNum - 1; i++)
            {
                if (pCorrCptsLt[i].FrCpt.isCtrl == false || pCorrCptsLt[i + 1].FrCpt.isCtrl == false)
                {
                    cpl.SubCPlLt[i].dblLengthV = cpl.SubCPlLt[i].pPolyline.Length - adblLength0[i];
                    //double dblLength = cpl.SubCPlLt[i].Length;
                    //double dblLength0 = adblLength0[i];


                    intUnKnownCountL6 += 1;
                }
                else
                {
                    cpl.SubCPlLt[i].dblLengthV = 0;
                }
            }

            int intUnKnownCountA6 = 0;

            for (int i = 0; i < intPtNum - 2; i++)
            {
                if (pCorrCptsLt[i].FrCpt.isCtrl == false || pCorrCptsLt[i + 1].FrCpt.isCtrl == false || pCorrCptsLt[i + 2].FrCpt.isCtrl == false)
                {
                    double dblAngle = CGeoFunc.CalAngle_Counterclockwise(cpl.CptLt[i], cpl.CptLt[i + 1], cpl.CptLt[i + 2]);
                    cpl.CptLt[i + 1].dblAngleV = dblAngle - adblAngle0[i];
                    //double dblAngle = CGeoFunc.CalAngle_Counterclockwise(cpl.CptLt[i], cpl.CptLt[i + 1], cpl.CptLt[i + 2]);
                    //cpl.CptLt[i + 1].dblAngleV = V[intUnknownLength + intUnKnownCountA6, 0];
                    intUnKnownCountA6 += 1;
                }
                else
                {
                    cpl.CptLt[i + 1].dblAngleV = 0;
                }
            }

            return(cpl);
        }
Exemplo n.º 2
0
        /// <summary>
        /// 获取线状要素
        /// </summary>
        /// <param name="pDataRecords">数据记录</param>
        /// <param name="dblProp">插值参数</param>
        /// <returns>在处理面状要素时,本程序将原面状要素的边界切开,按线状要素处理,处理完后再重新生成面状要素</returns>
        public CPolyline GetTargetcpl(double dblProp, CPolyline lastcpl)
        {
            //this.intIterationNum = Convert.ToInt32(_DataRecords.ParameterInitialize .txtIterationNum  .Text );

            if (dblProp == 0)
            {
                int aa = 5;
            }
            //intIterationNum = Convert.ToInt32(_DataRecords.ParameterInitialize.txtIterationNum.Text);     //the maximum itrative times
            List <CCorrCpts> pCorrCptsLt = _DataRecords.ParameterResult.CCorrCptsLt;   //读取数据后,此处ResultPtLt中的对应点为一一对应
            double           dblTX       = _dblTX;

            int intPtNum = pCorrCptsLt.Count;
            int intXYNum = 2 * intPtNum;

            ////generate the list of vertices based on linear interpolation
            //List<CPoint> newcptlt = new List<CPoint>();
            //for (int i = 0; i < pCorrCptsLt.Count ; i++)
            //{
            //    double dblnewx = (1 - dblProp) * pCorrCptsLt[i].FrCpt.X + dblProp * pCorrCptsLt[i].ToCpt.X;
            //    double dblnewy = (1 - dblProp) * pCorrCptsLt[i].FrCpt.Y + dblProp * pCorrCptsLt[i].ToCpt.Y;
            //    CPoint newcpt = new CPoint(i, dblnewx, dblnewy);
            //    newcptlt.Add(newcpt);
            //}


            //计算长度初始值(全部计算)
            double dblTune = 3;

            double[] adblLength0     = new double[intPtNum - 1];
            double   dblSumFrLength0 = 0;
            double   dblSumToLength0 = 0;

            for (int i = 0; i < pCorrCptsLt.Count - 1; i++)
            {
                double dblfrsublength = CGeoFunc.CalDis(pCorrCptsLt[i + 1].FrCpt, pCorrCptsLt[i].FrCpt);
                double dbltosublength = CGeoFunc.CalDis(pCorrCptsLt[i + 1].ToCpt, pCorrCptsLt[i].ToCpt);

                //double dble=Math .E;
                //double dbla = (dblfrsublength - dbltosublength) * dble / (dble - 1);
                //double dblb = (dble * dbltosublength - dblfrsublength) / (dble - 1);

                //adblLength0[i] = dbla * Math.Pow(dble, -dblProp) + dblb;



                adblLength0[i] = (1 - dblProp) * dblfrsublength + dblProp * dbltosublength;

                //adblLength0[i] = (1 - Math.Pow(dblProp, 1 / dblTune)) * dblfrsublength + Math.Pow(dblProp, 1 / dblTune) * dbltosublength;
                //dblSumFrLength0 = dblSumFrLength0 + dblfrsublength;
                //dblSumToLength0 = dblSumToLength0 + dbltosublength;

                //pCorrCptsLt[i].FrCpt.isCtrl = false;  //仅以最开始两对和最终两队对应点为固定点,故此先设置为false
            }

            //double dblFrRealSumLength = dblSumFrLength0 - CGeoFunc.CalDis(pCorrCptsLt[0].FrCpt, pCorrCptsLt[1].FrCpt) - CGeoFunc.CalDis(pCorrCptsLt[intPtNum - 2].FrCpt, pCorrCptsLt[intPtNum - 1].FrCpt);
            //double dblToRealSumLength = dblSumToLength0 - CGeoFunc.CalDis(pCorrCptsLt[0].ToCpt, pCorrCptsLt[1].ToCpt) - CGeoFunc.CalDis(pCorrCptsLt[intPtNum - 2].ToCpt, pCorrCptsLt[intPtNum - 1].ToCpt);

            //计算角度初始值(全部计算)
            double[] adblAngle0     = new double[intPtNum - 2];
            double   dblSumFrAngle0 = 0;
            double   dblSumToAngle0 = 0;

            for (int i = 0; i < pCorrCptsLt.Count - 2; i++)
            {
                //较大比例尺线状要素上的夹角
                double dblfrAngle = CGeoFunc.CalAngle_Counterclockwise(pCorrCptsLt[i].FrCpt,
                                                                       pCorrCptsLt[i + 1].FrCpt, pCorrCptsLt[i + 2].FrCpt);
                //较小比例尺线状要素上的夹角
                double dbltoAngle = CGeoFunc.CalAngle_Counterclockwise(pCorrCptsLt[i].ToCpt,
                                                                       pCorrCptsLt[i + 1].ToCpt, pCorrCptsLt[i + 2].ToCpt);

                //double dble = Math.E;
                //double dbla = (dbltoAngle - dblfrAngle) * dble / (dble - 1);
                //double dblb = (dble * dblfrAngle - dbltoAngle) / (dble - 1);

                ////角度初始值
                //adblAngle0[i] = dbla * Math.Pow(dble, dblProp-1) + dblb;

                adblAngle0[i] = (1 - dblProp) * dblfrAngle + dblProp * dbltoAngle;

                //adblAngle0[i] = (1 - Math.Pow(dblProp, dblTune)) * dblfrAngle + Math.Pow(dblProp, dblTune) * dbltoAngle;

                //dblSumFrAngle0 = dblSumFrAngle0 + dblfrAngle;
                //dblSumToAngle0 = dblSumToAngle0 + dbltoAngle;
            }
            //double dblLengthAngleRatio = (dblSumFrToLength0 / (pCorrCptsLt.Count - 1)) / (dblSumFrToAngle0 / (pCorrCptsLt.Count - 2));

            //for (int i = 0; i < pCorrCptsLt.Count - 2; i++)
            //{
            //    adblAngle0[i] = CGeoFunc.CalAngle_Counterclockwise(newcptlt[i], newcptlt[i + 1], newcptlt[i + 2]);
            //}


            //计算坐标初始值,以及各线段方位角初始值


            //for (int i = 0; i < pCorrCptsLt.Count; i++)
            //{
            //    pCorrCptsLt[i].FrCpt.isCtrl = false;
            //}
            //注意:默认固定第一条边
            pCorrCptsLt[0].FrCpt.isCtrl = true;
            pCorrCptsLt[1].FrCpt.isCtrl = true;
            //固定最后两条边
            pCorrCptsLt[intPtNum - 2].FrCpt.isCtrl = true;
            pCorrCptsLt[intPtNum - 1].FrCpt.isCtrl = true;


            //统计插值点数
            int intKnownPt   = 0;                               //固定点的数目
            int intUnknownPt = 0;                               //非固定点的数目

            bool[]     isFixed            = new bool[intPtNum]; // is vertex i fixed?
            List <int> intKnownLocationLt = new List <int>();   //记录已知点的序号

            //注意:对于该循环,有一个默认条件,即FromCpl的第一个顶点只有一个对应点
            for (int i = 0; i < pCorrCptsLt.Count; i++)
            {
                if (pCorrCptsLt[i].FrCpt.isCtrl == true)
                {
                    intKnownLocationLt.Add(i);
                    intKnownPt += 1;

                    isFixed[i] = true;
                }
                else
                {
                    intUnknownPt += 1;
                }
            }
            int intUnknownXY = intUnknownPt * 2;   //每个点都有X、Y坐标

            //找出长度固定的位置(如果一个线段的前后两个点都固定,则该长度固定)。另外,长度固定则该边的方位角也固定
            List <int> intKnownLengthLt = new List <int>();

            for (int i = 0; i < intKnownLocationLt.Count - 1; i++)
            {
                if ((intKnownLocationLt[i + 1] - intKnownLocationLt[i]) == 1)
                {
                    intKnownLengthLt.Add(intKnownLocationLt[i]);
                }
            }
            int intUnknownLength = intPtNum - 1 - intKnownLengthLt.Count;

            //找出角度固定的位置(如果一个固定顶点的前后两个点都固定,则该角度固定)
            List <int> intKnownAngleLt = new List <int>();

            for (int i = 0; i < intKnownLocationLt.Count - 2; i++)
            {
                if ((intKnownLocationLt[i + 1] - intKnownLocationLt[i]) == 1 &&
                    (intKnownLocationLt[i + 2] - intKnownLocationLt[i + 1]) == 1)
                {
                    intKnownAngleLt.Add(intKnownLocationLt[i]);
                }
            }
            int intUnknownAngle = intPtNum - 2 - intKnownAngleLt.Count;

            //总未知量
            int           intUnknownLengthAngle = intUnknownLength + intUnknownAngle;
            List <CPoint> lastcptlt             = lastcpl.CptLt;


            #region new codes
            ////以上一次结果的值作为新的估算值
            double[] adblx = new double[intPtNum];
            double[] adbly = new double[intPtNum];

            for (int i = 0; i < intPtNum; i++)
            {
                if (pCorrCptsLt[i].FrCpt.isCtrl == false)
                {
                    adblx[i] = lastcptlt[i].X;
                    adbly[i] = lastcptlt[i].Y;
                }
                else
                {
                    adblx[i] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.X + dblProp * pCorrCptsLt[i].ToCpt.X;
                    adbly[i] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.Y + dblProp * pCorrCptsLt[i].ToCpt.Y;
                }
            }

            double[] weight = new double[intUnknownLengthAngle];
            for (int i = 0; i < intUnknownLength; i++)
            {
                weight[i] = 1;
                //weight[i] = 0.0036;
            }
            for (int i = 0; i < intUnknownAngle; i++)
            {
                weight[intUnknownLength + i] = 39.48;
            }


            double[] xout = new double[intPtNum];
            double[] yout = new double[intPtNum];
            //CPlusClass.Matrix.leastSquaresAdjust(intPtNum, adblx, adbly, isFixed,
            //adblLength0, adblAngle0, weight, dblTX, intIterationNum, xout, yout);

            //MessageBox.Show("" + xout[5]);


            //生成目标线段
            List <CPoint> CTargetPtLt = new List <CPoint>();
            for (int i = 0; i < intPtNum; i++)
            {
                CPoint cpt = new CPoint(i);
                cpt.X = xout[i];
                cpt.Y = yout[i];

                if (pCorrCptsLt[i].FrCpt.isCtrl == true)
                {
                    cpt.isCtrl = true;
                }
                else
                {
                    cpt.isCtrl = false;
                }

                CTargetPtLt.Add(cpt);
            }
            CPolyline cpl = new CPolyline(0, CTargetPtLt);
            cpl.CreateSubPllt();
            #endregion



            #region old codes

            ////定义权重矩阵***************************************************************************************定义权重矩阵************************************************************************************************定义权重矩阵//
            //VBMatrix P = new VBMatrix(intUnknownLengthAngle, intUnknownLengthAngle);
            //for (int i = 0; i < intUnknownLength; i++)
            //{
            //    P[i, i] = 0.0036;
            //}
            //for (int i = 0; i < intUnknownAngle; i++)
            //{
            //    P[intUnknownLength + i, intUnknownLength + i] = 40;
            //    //P[intUnknownLength + i, intUnknownLength + i] = 0.0002;
            //}

            ////以上一次结果的值作为新的估算值
            //VBMatrix X0 = new VBMatrix(intXYNum, 1);
            //for (int i = 0; i < intPtNum; i++)
            //{
            //    if (pCorrCptsLt[i].FrCpt.isCtrl == false)
            //    {
            //        X0[2 * i + 0, 0] = lastcptlt[i].X;
            //        X0[2 * i + 1, 0] = lastcptlt[i].Y;
            //    }
            //    else
            //    {
            //        X0[2 * i + 0, 0] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.X + dblProp * pCorrCptsLt[i].ToCpt.X;
            //        X0[2 * i + 1, 0] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.Y + dblProp * pCorrCptsLt[i].ToCpt.Y;
            //    }
            //}

            ////定义坐标近似值矩阵XA
            //VBMatrix XA = new VBMatrix(intUnknownXY, 1);
            //VBMatrix XA0 = new VBMatrix(intUnknownXY, 1);
            //int intSumCount0 = 0;
            //for (int i = 0; i < intUnknownPt; i++)
            //{
            //    if (pCorrCptsLt[intSumCount0].FrCpt.isCtrl == false)
            //    {
            //        XA[i * 2 + 0, 0] = X0[intSumCount0 * 2, 0];
            //        XA[i * 2 + 1, 0] = X0[intSumCount0 * 2 + 1, 0];

            //        XA0[i * 2 + 0, 0] = XA[i * 2 + 0, 0];
            //        XA0[i * 2 + 1, 0] = XA[i * 2 + 1, 0];
            //    }
            //    else
            //    {
            //        i -= 1;
            //    }
            //    intSumCount0 += 1;
            //}


            ////Xmix里存储了XA和X0的最新混合值(此矩阵在公式推导中并不存在,只是为了方便编写代码而建立)
            //VBMatrix Xmix = new VBMatrix(intXYNum, 1);
            //for (int i = 0; i < intXYNum; i++)
            //{
            //    Xmix[i, 0] = X0[i, 0];
            //}

            ////近似值与观测值之差matl,平差中的-l
            //VBMatrix matl = new VBMatrix(intUnknownLengthAngle, 1);

            ////定义系数矩阵A(各方程对坐标的导数值),A的导数值将在循环中给出
            //VBMatrix A = new VBMatrix(intUnknownLengthAngle, intUnknownXY);
            //VBMatrix V = new VBMatrix();
            //double dblJudge1 = 0;   //该值用于判断是否应该跳出循环
            //double dblJudge2 = 0;   //该值用于判断是否应该跳出循环
            //int intJudgeIndex = intUnknownLength / 4;
            //int intIterativeCount = 0;
            //double[] adblSubDis = new double[intPtNum - 1];
            //double[] adblAngle = new double[intPtNum - 2];
            //double[] adblAzimuth = new double[intPtNum - 1]; ;
            //VBMatrix LPlusV = new VBMatrix(intUnknownLengthAngle, 1);
            //do
            //{
            //    //计算系数矩阵A第0行到"intUnknownLength"行的各元素,即线段长度对各未知数求偏导的值
            //    //先计算各分母值(注意:分母实际上是求偏导后的一部分值,但却恰好等于两点之间距离,因此其计算公式与距离计算公式相同
            //    adblSubDis = new double[intPtNum - 1];
            //    for (int i = 0; i < intPtNum - 1; i++)
            //    {
            //        adblSubDis[i] = Math.Pow((Xmix[2 * i, 0] - Xmix[2 * i + 2, 0]) * (Xmix[2 * i, 0] - Xmix[2 * i + 2, 0]) + (Xmix[2 * i + 1, 0] - Xmix[2 * i + 3, 0]) * (Xmix[2 * i + 1, 0] - Xmix[2 * i + 3, 0]), 0.5);
            //    }
            //    //计算新的方位角
            //    adblAzimuth[0] = CGeoFunc.CalAxisAngle(Xmix[0, 0], Xmix[1, 0], Xmix[2, 0], Xmix[3, 0]);
            //    for (int i = 1; i < intPtNum - 1; i++)
            //    {
            //        adblAngle[i - 1] = CGeoFunc.CalAngle_Counterclockwise(Xmix[i * 2 - 2, 0], Xmix[i * 2 - 1, 0], Xmix[i * 2, 0], Xmix[i * 2 + 1, 0], Xmix[i * 2 + 2, 0], Xmix[i * 2 + 3, 0]);
            //        adblAzimuth[i] = adblAzimuth[i - 1] + adblAngle[i - 1] - Math.PI;
            //    }


            //    //计算系数矩阵中关于长度值的导数部分
            //    _pCAL.CalADevLength(pCorrCptsLt, 0, intUnknownLength, ref A, ref matl, adblSubDis, adblAzimuth, adblLength0);


            //    //计算系数矩阵中关于夹角值的导数部分
            //    _pCAL.CalADevAngle(pCorrCptsLt, intUnknownLength, intUnknownAngle, Xmix, ref A, ref matl, adblSubDis, adblAngle, adblAngle0);



            //    //CHelpFuncExcel.ExportDataToExcel2(A, "maxA", _DataRecords.ParameterInitialize.strSavePath);
            //    //CHelpFuncExcel.ExportDataToExcelP(P, "maxP", _DataRecords.ParameterInitialize.strSavePath);
            //    //CHelpFuncExcel.ExportDataToExcel2(matl, "maxmatl", _DataRecords.ParameterInitialize.strSavePath);


            //    //平差
            //    VBMatrix Temp = A.Trans() * P * A;
            //    VBMatrix InvTemp = Temp.Inv(Temp);
            //    VBMatrix x = InvTemp * A.Trans() * P * matl;

            //    //CHelpFuncExcel.ExportDataToExcel2(x, "maxX", _DataRecords.ParameterInitialize.strSavePath);

            //    XA += x;

            //    //CHelpFuncExcel.ExportDataToExcel2(x, "maxX", _DataRecords.ParameterInitialize.strSavePath);
            //    //CHelpFuncExcel.ExportDataToExcel2(XA, "maxXA", _DataRecords.ParameterInitialize.strSavePath);


            //    V = A * x - matl;
            //    //VtPV值
            //    double dblVtPV = (V.Trans() * P * V).MatData[0, 0];
            //    //XA -= x;
            //    _DataRecords.ParameterInitialize.txtVtPV.Text = "   VtPV = " + dblVtPV.ToString();


            //    //VBMatrix L = new VBMatrix(intUnknownLengthAngle, 1);
            //    //for (int j = 0; j < intUnknownLength; j++)
            //    //{
            //    //    L[j, 0] = adblSubDis[j];
            //    //}
            //    //for (int j = 0; j < intUnknownAngle; j++)
            //    //{
            //    //    L[intUnknownLength+ j, 0] = adblAngle[j];
            //    //}

            //    //LPlusV = L + V;



            //    //对坐标值进行改正
            //    int intSumCount5 = 0;
            //    for (int i = 0; i < intUnknownPt; i++)
            //    {
            //        if (pCorrCptsLt[intSumCount5].FrCpt.isCtrl == false)
            //        {
            //            Xmix[intSumCount5 * 2 + 0, 0] = XA[i * 2 + 0, 0];
            //            Xmix[intSumCount5 * 2 + 1, 0] = XA[i * 2 + 1, 0];
            //        }
            //        else
            //        {
            //            i -= 1;
            //        }
            //        intSumCount5 += 1;
            //    }


            //    ////计算系数矩阵A第0行到"intUnknownLength"行的各元素,即线段长度对各未知数求偏导的值
            //    ////先计算各分母值(注意:分母实际上是求偏导后的一部分值,但却恰好等于两点之间距离,因此其计算公式与距离计算公式相同
            //    //for (int i = 0; i < intPtNum - 1; i++)
            //    //{
            //    //    L[i,0] = Math.Pow((Xmix[2 * i, 0] - Xmix[2 * i + 2, 0]) * (Xmix[2 * i, 0] - Xmix[2 * i + 2, 0]) + (Xmix[2 * i + 1, 0] - Xmix[2 * i + 3, 0]) * (Xmix[2 * i + 1, 0] - Xmix[2 * i + 3, 0]), 0.5);
            //    //}
            //    ////计算新的方位角
            //    //adblAzimuth[0] = CGeoFunc.CalAxisAngle(Xmix[0, 0], Xmix[1, 0], Xmix[2, 0], Xmix[3, 0]);
            //    //for (int i = 1; i < intPtNum - 1; i++)
            //    //{
            //    //    L[intUnknownLength + i -1, 0] = CGeoFunc.CalAngle_Counterclockwise(Xmix[i * 2 - 2, 0], Xmix[i * 2 - 1, 0], Xmix[i * 2, 0], Xmix[i * 2 + 1, 0], Xmix[i * 2 + 2, 0], Xmix[i * 2 + 3, 0]);
            //    //}



            //    //CHelpFuncExcel.ExportDataToExcel2(LPlusV, "matLPlusV", _DataRecords.ParameterInitialize.strSavePath);
            //    //CHelpFuncExcel.ExportDataToExcel2(L, "matL", _DataRecords.ParameterInitialize.strSavePath);



            //    if (intIterativeCount == 50)
            //    {
            //        int kk = 5;
            //    }

            //    intIterativeCount += 1;


            //    if (intIterativeCount >= intIterationNum)
            //    {
            //        break;
            //    }

            //    //这里只是随便取两个中间值以观测是否收敛
            //    double dblLength0 = CGeoFunc.CalLengthofVector(x);
            //    if (dblLength0 <= dblTX)
            //    {
            //        break;
            //    }

            //} while (true);



            ////生成目标线段
            //List<CPoint> CTargetPtLt = new List<CPoint>();
            //for (int i = 0; i < intPtNum; i++)
            //{
            //    CPoint cpt = new CPoint(i);
            //    cpt.X = Xmix[2 * i, 0];
            //    cpt.Y = Xmix[2 * i + 1, 0];

            //    if (pCorrCptsLt[i].FrCpt.isCtrl == true)
            //    {
            //        cpt.isCtrl = true;
            //    }
            //    else
            //    {
            //        cpt.isCtrl = false;
            //    }

            //    CTargetPtLt.Add(cpt);
            //}
            //CPolyline cpl = new CPolyline(0, CTargetPtLt);
            //cpl.CreateSubPllt();
            #endregion



            ////记录各平差成果
            ////坐标改正值
            //VBMatrix Xc = XA-XA0;
            ////观测值改正值矩阵V
            //VBMatrix V = A * Xc + matl;
            ////VtPV值
            //cpl.dblVtPV = (V.Trans() * P * V).MatData[0, 0];


            //VBMatrix VLength = V.GetSubMatrix(0, intUnknownLength, 0, 1);
            //VBMatrix VAngle = V.GetSubMatrix(intUnknownLength, intUnknownAngle, 0, 1);

            //VBMatrix PLength = P.GetSubMatrix(0, intUnknownLength, 0, intUnknownLength);
            //VBMatrix PAngle = P.GetSubMatrix(intUnknownLength, intUnknownAngle, intUnknownLength, intUnknownAngle);

            //VBMatrix VtPVLength = VLength.Trans() * PLength * VLength;
            //VBMatrix VtPVAngle = VAngle.Trans() * PAngle * VAngle;

            //double dblVtPVLength = VtPVLength[0, 0];
            //double dblVtPVAngle = VtPVAngle[0, 0];
            //double pdblVtPV = (V.Trans() * P * V)[0, 0];



            //double ss = dblProp;
            ////
            //int intUnKnownCountL6 = 0;
            //for (int i = 0; i < intPtNum - 1; i++)
            //{
            //    if (pCorrCptsLt[i].FrCpt.isCtrl == false || pCorrCptsLt[i + 1].FrCpt.isCtrl == false)
            //    {
            //        cpl.SubCPlLt[i].dblLengthV = cpl.SubCPlLt[i].Length - adblLength0[i];
            //        //double dblLength = cpl.SubCPlLt[i].Length;
            //        //double dblLength0 = adblLength0[i];


            //        intUnKnownCountL6 += 1;
            //    }
            //    else
            //    {
            //        cpl.SubCPlLt[i].dblLengthV = 0;
            //    }
            //}

            //int intUnKnownCountA6 = 0;
            //for (int i = 0; i < intPtNum - 2; i++)
            //{
            //    if (pCorrCptsLt[i].FrCpt.isCtrl == false || pCorrCptsLt[i + 1].FrCpt.isCtrl == false || pCorrCptsLt[i + 2].FrCpt.isCtrl == false)
            //    {
            //        double dblAngle = CGeoFunc.CalAngle_Counterclockwise(cpl.CptLt[i], cpl.CptLt[i + 1], cpl.CptLt[i + 2]);
            //        cpl.CptLt[i + 1].dblAngleV = dblAngle - adblAngle0[i];
            //        //double dblAngle = CGeoFunc.CalAngle_Counterclockwise(cpl.CptLt[i], cpl.CptLt[i + 1], cpl.CptLt[i + 2]);
            //        //cpl.CptLt[i + 1].dblAngleV = V[intUnknownLength + intUnKnownCountA6, 0];
            //        intUnKnownCountA6 += 1;
            //    }
            //    else
            //    {
            //        cpl.CptLt[i + 1].dblAngleV = 0;
            //    }
            //}
            //intIterationNum++;
            return(cpl);

            //return null;
        }