private IEnumerable <CPolyline> GenerateSeparateLinkCplEb(CPolyline frcpl1, CPolyline tocpl1, CPolyline frcpl2, CPolyline tocpl2,
                                                                  int intIndex1, int intIndex2, double dblMid, string strDimension)
        {
            var SeparateLinkCplEb1 = GenerateOneSeparateLinkCplEb(frcpl1, tocpl1, intIndex1, intIndex2, dblMid, strDimension);
            var SeparateLinkCplEb2 = GenerateOneSeparateLinkCplEb(frcpl2, tocpl2, intIndex1, intIndex2, dblMid, strDimension);

            return(SeparateLinkCplEb1.Concat(SeparateLinkCplEb2));
        }
        /// <summary>
        /// 提取对应线段
        /// </summary>
        /// <param name="frcpl">大比例尺线状要素</param>
        /// <param name="tocpl">小比例尺线状要素</param>
        /// <param name="pCorrespondBendLt">对应弯曲列表</param>
        /// <returns>对应线段</returns>
        /// <remarks></remarks>
        public static SCG.LinkedList <CCorrSegment> DetectCorrespondSegment(CPolyline frcpl, CPolyline tocpl, List <CCorrespondBend> pCorrespondBendLt)
        {
            //提取对应弯曲的首尾点为对应特征点
            SortedList <double, CCorrCpts> pCorrespondingCptSlt = new SortedList <double, CCorrCpts>(new CCmpDbl());

            CCorrCpts pStartCorrespondingCpt0 = new CCorrCpts(frcpl.CptLt[0], tocpl.CptLt[0]);                                         //第一对对应特征点
            CCorrCpts pEndCorrespondingCpt0   = new CCorrCpts(frcpl.CptLt[frcpl.CptLt.Count - 1], tocpl.CptLt[tocpl.CptLt.Count - 1]); //第二对对应特征点

            pCorrespondingCptSlt.Add(0, pStartCorrespondingCpt0);
            pCorrespondingCptSlt.Add(1, pEndCorrespondingCpt0);

            //其它对应特征点
            for (int i = 0; i < pCorrespondBendLt.Count; i++)
            {
                CCorrCpts pStartCorrespondingCpt = new CCorrCpts(pCorrespondBendLt[i].CFromBend.CptLt[0], pCorrespondBendLt[i].CToBend.CptLt[0]);
                CCorrCpts pEndCorrespondingCpt   = new CCorrCpts(
                    pCorrespondBendLt[i].CFromBend.CptLt[pCorrespondBendLt[i].CFromBend.CptLt.Count - 1],
                    pCorrespondBendLt[i].CToBend.CptLt[pCorrespondBendLt[i].CToBend.CptLt.Count - 1]);

                pCorrespondingCptSlt.Add(pCorrespondBendLt[i].CFromBend.dblStartRL, pStartCorrespondingCpt);
                pCorrespondingCptSlt.Add(pCorrespondBendLt[i].CFromBend.dblEndRL, pEndCorrespondingCpt);
            }


            //查找并删除重复对应特征点
            for (int i = pCorrespondingCptSlt.Count - 1; i > 0; i--)
            {
                CPoint frcpt2 = pCorrespondingCptSlt.Values[i].FrCpt;
                CPoint tocpt2 = pCorrespondingCptSlt.Values[i].ToCpt;
                CPoint frcpt1 = pCorrespondingCptSlt.Values[i - 1].FrCpt;
                CPoint tocpt1 = pCorrespondingCptSlt.Values[i - 1].ToCpt;
                if (frcpt1.Equals2D(frcpt2) && tocpt1.Equals2D(tocpt2))
                {
                    pCorrespondingCptSlt.RemoveAt(i);
                }
            }

            //以对应特征点为断点分割原始线段,得到对应线段
            SCG.LinkedList <CCorrSegment> pCorrespondSegmentLk = new SCG.LinkedList <CCorrSegment>();

            //中间的对应线段
            for (int i = 0; i < pCorrespondingCptSlt.Count - 1; i++)
            {
                CPolyline frSegment = frcpl.GetSubPolyline(pCorrespondingCptSlt.Values[i].FrCpt, pCorrespondingCptSlt.Values[i + 1].FrCpt);
                CPolyline toSegment = tocpl.GetSubPolyline(pCorrespondingCptSlt.Values[i].ToCpt, pCorrespondingCptSlt.Values[i + 1].ToCpt);
                pCorrespondSegmentLk.AddLast(new CCorrSegment(frSegment, toSegment));
            }

            return(pCorrespondSegmentLk);
        }
        private IEnumerable <CPolyline> GenerateVarioLinkCplEb(CPolyline frcpl1, CPolyline tocpl1, CPolyline frcpl2, CPolyline tocpl2,
                                                               int intIndex1, int intIndex2)
        {
            yield return(new CPolyline(frcpl1.CptLt[intIndex1], tocpl1.CptLt[intIndex1]));

            yield return(new CPolyline(frcpl1.CptLt[intIndex2], tocpl1.CptLt[intIndex2]));

            yield return(new CPolyline(frcpl2.CptLt[intIndex1], tocpl2.CptLt[intIndex1]));

            yield return(new CPolyline(frcpl2.CptLt[intIndex2], tocpl2.CptLt[intIndex2]));
        }
        /// <summary>以回溯的方式寻找对应线段</summary>
        /// <param name="frcpl">大比例尺线状要素</param>
        /// <param name="tocpl">小比例尺线状要素</param>
        /// <param name="CFrEdgeLt">大比例尺线段</param>
        ///  <param name="CToEdgeLt">小比例尺线段</param>
        /// <param name="frlastcpllt">大比例尺终点线段(只有一个点)</param>
        /// <param name="tolastcpllt">小比例尺终点线段(只有一个点)</param>
        /// <returns>对应线段数组</returns>
        public LinkedList <CCorrSegment> FindCorrespondSegmentLk(CTable[,] T, CPolyline frcpl, CPolyline tocpl, List <CPolyline> CFrBezierEdgeLt, List <CPolyline> CToBezierEdgeLt, List <CPolyline> frlastcpllt, List <CPolyline> tolastcpllt)
        {
            //LinkedList<CCorrSegment> CorrespondSegmentLk = new LinkedList<CCorrSegment>();
            //int i = CFrBezierEdgeLt.Count;
            //int j = CToBezierEdgeLt.Count;

            //while (i >= 0 && j >= 0)
            //{
            //    CPolyline frcplw = new CPolyline();
            //    CPolyline tocplw = new CPolyline();
            //    if (i == 0 && j == 0)
            //    {
            //        break;
            //    }
            //    else if (i == 0 && j > 0)  //第0行的情况
            //    {
            //        frcplw = new CPolyline(0, CFrBezierEdgeLt[0].CptLt[0]);
            //        tocplw = tocpl.GetSubPolyline(CToBezierEdgeLt[0].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[1]);
            //        j = 0;
            //    }
            //    else if (i > 0 && j == 0)  //第0列的情况
            //    {
            //        frcplw = frcpl.GetSubPolyline(CFrBezierEdgeLt[0].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[1]);
            //        tocplw = new CPolyline(0, CToBezierEdgeLt[0].CptLt[0]);
            //        i = 0;
            //    }
            //    else  //其它行列的情况
            //    {
            //        if (T[i, j].frpart == "segment" && T[i, j].topart == "last")
            //        {
            //            frcplw = frcpl.GetSubPolyline(CFrBezierEdgeLt[i - 1].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[1]);
            //            tocplw = tolastcpllt[j - 1];
            //            i = i - 1;
            //        }
            //        else if (T[i, j].frpart == "last" && T[i, j].topart == "segment")
            //        {
            //            frcplw = frlastcpllt[i - 1];
            //            tocplw = tocpl.GetSubPolyline(CToBezierEdgeLt[j - 1].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[1]);
            //            j = j - 1;
            //        }
            //        else if (T[i, j].frpart == "segment" && T[i, j].topart == "segment")
            //        {
            //            frcplw = frcpl.GetSubPolyline(CFrBezierEdgeLt[i - 1].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[1]);
            //            tocplw = tocpl.GetSubPolyline(CToBezierEdgeLt[j - 1].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[1]);
            //            i = i - 1;
            //            j = j - 1;
            //        }
            //        else if (T[i, j].frpart == "segment" && T[i, j].topart == "multisegments")
            //        {
            //            frcplw = frcpl.GetSubPolyline(CFrBezierEdgeLt[i - 1].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[1]);
            //            tocplw = tocpl.GetSubPolyline(CToBezierEdgeLt[j - T[i, j].intBackK].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[1]);
            //            j = j - T[i, j].intBackK;
            //            i = i - 1;
            //        }
            //        else if (T[i, j].frpart == "multisegments" && T[i, j].topart == "segment")
            //        {
            //            frcplw = frcpl.GetSubPolyline(CFrBezierEdgeLt[i - T[i, j].intBackK].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[1]);
            //            tocplw = tocpl.GetSubPolyline(CToBezierEdgeLt[j - 1].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[1]);
            //            i = i - T[i, j].intBackK;
            //            j = j - 1;
            //        }
            //    }

            //    CCorrSegment pCorrespondSegment = new CCorrSegment();
            //    pCorrespondSegment = new CCorrSegment(frcplw, tocplw);
            //    CorrespondSegmentLk.AddFirst(pCorrespondSegment);

            //}

            //return CorrespondSegmentLk;
            return(null);
        }
 private void btn100_Click(object sender, EventArgs e)
 {
     _dblProp = 1;
     _RelativeInterpolationCpl = CDrawInActiveView.DisplayInterpolation(_DataRecords, _dblProp);
 }
        public void STS()
        {
            var pParameterInitialize = _ParameterInitialize;
            var pAxMapControl        = pParameterInitialize.pAxMapControl;


            pAxMapControl.Dock   = DockStyle.None;
            pAxMapControl.Width  = 310;
            pAxMapControl.Height = 310;
            double dblWHRation = pAxMapControl.Width / pAxMapControl.Height;

            double dblCenterX = 318;
            double dblCenterY = 345;
            //IPoint cptMC = new PointClass();
            //cptMC.PutCoords(170, 180);

            IEnvelope newEnvelope = new EnvelopeClass();
            double    dblRatio    = 1;

            newEnvelope.XMin = dblCenterX - pAxMapControl.Width / dblRatio;
            newEnvelope.XMax = dblCenterX + pAxMapControl.Width / dblRatio;
            newEnvelope.YMin = dblCenterY - pAxMapControl.Height / dblRatio;
            newEnvelope.YMax = dblCenterY + pAxMapControl.Height / dblRatio;
            //newEnvelope.XMin = dblCenterX - pAxMapControl.Width ;
            //newEnvelope.XMax = dblCenterX + pAxMapControl.Width ;
            //newEnvelope.YMin = dblCenterY - pAxMapControl.Height ;
            //newEnvelope.YMax = dblCenterY + pAxMapControl.Height;
            pAxMapControl.Extent = newEnvelope;

            //pAxMapControl.MapScale = 1 / 6000000;
            //pAxMapControl.CenterAt(cptMC);
            //Old Larger-scale, Old Smaller-scale, New Larger-scale, New Smaller-scale
            _OLCplLt = this.ObjCGeoLtLt[0].Select(cgeo => cgeo as CPolyline).ToList();
            _OSCplLt = this.ObjCGeoLtLt[1].Select(cgeo => cgeo as CPolyline).ToList();
            _NLCplLt = this.ObjCGeoLtLt[2].Select(cgeo => cgeo as CPolyline).ToList();
            _NSCplLt = this.ObjCGeoLtLt[3].Select(cgeo => cgeo as CPolyline).ToList();


            var olcpl = _OLCplLt[0];
            var oscpl = _OSCplLt[0];
            var nlcpl = _NLCplLt[0];
            var nscpl = _NSCplLt[0];

            double dblXAxisStart = 50;
            double dblXAxisEnd   = 620;
            double dblYAxisStart = 70;
            double dblYAxisEnd   = 620;

            double dblScaleMidY = (olcpl.CptLt[0].Y + oscpl.CptLt[0].Y) / 2;
            double dblTimeMidX  = (olcpl.CptLt[4].X + nlcpl.CptLt[4].X) / 2;

            var strTS             = _ParameterInitialize.strTS;
            var LinkCplLt         = new List <CPolyline>();
            var SeparatorCplLt    = new List <CPolyline>();
            var scaleSeparatorCpl = new CPolyline(
                new CPoint(dblXAxisStart + 5, dblScaleMidY), new CPoint(dblXAxisEnd - 5, dblScaleMidY));
            var timeSeparatorCpl = new CPolyline(
                new CPoint(dblTimeMidX, dblYAxisStart + 5), new CPoint(dblTimeMidX, dblYAxisEnd - 5));

            if (strTS == "vario_vario")
            {
                //time transition
                LinkCplLt.AddRange(GenerateVarioLinkCplEb(olcpl, nlcpl, oscpl, nscpl, 4, 12));
                //scale transition
                LinkCplLt.AddRange(GenerateVarioLinkCplEb(olcpl, oscpl, nlcpl, nscpl, 0, 8));
            }
            else if (strTS == "vario_separate")
            {
                //time transition
                LinkCplLt.AddRange(GenerateVarioLinkCplEb(olcpl, nlcpl, oscpl, nscpl, 4, 12));
                //scale transition
                LinkCplLt.AddRange(GenerateSeparateLinkCplEb(olcpl, oscpl, nlcpl, nscpl, 0, 8, dblScaleMidY, "Scale"));

                SeparatorCplLt.Add(scaleSeparatorCpl);
            }
            else if (strTS == "separate_vario")
            {
                //time transition
                LinkCplLt.AddRange(GenerateSeparateLinkCplEb(olcpl, nlcpl, oscpl, nscpl, 4, 12, dblTimeMidX, "Time"));
                //scale transition
                LinkCplLt.AddRange(GenerateVarioLinkCplEb(olcpl, oscpl, nlcpl, nscpl, 0, 8));

                SeparatorCplLt.Add(timeSeparatorCpl);
            }
            else //if (strTS == "separate_separate")
            {
                //time transition
                LinkCplLt.AddRange(GenerateSeparateLinkCplEb(olcpl, nlcpl, oscpl, nscpl, 4, 12, dblTimeMidX, "Time"));
                //scale transition
                LinkCplLt.AddRange(GenerateSeparateLinkCplEb(olcpl, oscpl, nlcpl, nscpl, 0, 8, dblScaleMidY, "Scale"));

                SeparatorCplLt.Add(scaleSeparatorCpl);
                SeparatorCplLt.Add(timeSeparatorCpl);
            }


            CSaveFeature.SaveCplEb(SeparatorCplLt, strTS + "_Separator", intRed: 204, intGreen: 204, intBlue: 204,
                                   pesriSimpleLineStyle: esriSimpleLineStyle.esriSLSDot);
            //pesriSimpleLineStyle: esriSimpleLineStyle.esriSLSDash);
            CSaveFeature.SaveCplEb(LinkCplLt, strTS + "_Link", intRed: 150, intGreen: 150, intBlue: 150);



            double dblXExtra   = 400;
            double dblYExtra   = 400;
            var    olIRgbColor = CHelpFunc.GenerateIRgbColor(230, 97, 1);
            var    nlIRgbColor = CHelpFunc.GenerateIRgbColor(94, 60, 153);


            var cpllt00 = Output(0.00, 0.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt10 = Output(0.33, 0.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt20 = Output(0.67, 0.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt30 = Output(1.00, 0.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);

            var cpllt01 = Output(0.00, 0.33, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt11 = Output(0.33, 0.33, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt21 = Output(0.67, 0.33, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt31 = Output(1.00, 0.33, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);

            var cpllt02 = Output(0.00, 0.67, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt12 = Output(0.33, 0.67, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt22 = Output(0.67, 0.67, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt32 = Output(1.00, 0.67, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);

            var cpllt03 = Output(0.00, 1.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt13 = Output(0.33, 1.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt23 = Output(0.67, 1.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);
            var cpllt33 = Output(1.00, 1.00, olIRgbColor, nlIRgbColor, dblXExtra, dblYExtra);

            double dblMinY00 = cpllt00[0].CptLt.Min(cpt => cpt.Y);
            double dblMinY01 = cpllt01[0].CptLt.Min(cpt => cpt.Y);
            double dblMinY02 = cpllt02[0].CptLt.Min(cpt => cpt.Y);
            double dblMinY03 = cpllt03[0].CptLt.Min(cpt => cpt.Y);

            double dblMaxY00 = cpllt00[0].CptLt.Max(cpt => cpt.Y);
            double dblMaxY01 = cpllt01[0].CptLt.Max(cpt => cpt.Y);
            double dblMaxY02 = cpllt02[0].CptLt.Max(cpt => cpt.Y);
            double dblMaxY03 = cpllt03[0].CptLt.Max(cpt => cpt.Y);

            double dblMidY00 = (dblMinY00 + dblMaxY00) / 2;
            double dblMidY01 = (dblMinY01 + dblMaxY01) / 2;
            double dblMidY02 = (dblMinY02 + dblMaxY02) / 2;
            double dblMidY03 = (dblMinY03 + dblMaxY03) / 2;


            double dblMinX00 = cpllt00[0].CptLt.Min(cpt => cpt.X);
            double dblMinX10 = cpllt10[0].CptLt.Min(cpt => cpt.X);
            double dblMinX20 = cpllt20[0].CptLt.Min(cpt => cpt.X);
            double dblMinX30 = cpllt30[0].CptLt.Min(cpt => cpt.X);

            double dblMaxX00 = cpllt00[0].CptLt.Max(cpt => cpt.X);
            double dblMaxX10 = cpllt10[0].CptLt.Max(cpt => cpt.X);
            double dblMaxX20 = cpllt20[0].CptLt.Max(cpt => cpt.X);
            double dblMaxX30 = cpllt30[0].CptLt.Max(cpt => cpt.X);

            double dblMidX00 = (dblMinX00 + dblMaxX00) / 2;
            double dblMidX10 = (dblMinX10 + dblMaxX10) / 2;
            double dblMidX20 = (dblMinX20 + dblMaxX20) / 2;
            double dblMidX30 = (dblMinX30 + dblMaxX30) / 2;



            double dblTextSize = 8;

            CDrawInActiveView.DrawArrow(pAxMapControl.ActiveView,
                                        new CPoint(dblXAxisStart - 30, dblYAxisStart), new CPoint(dblXAxisEnd, dblYAxisStart), 6, 5); //x arrow; horizontal
            CDrawInActiveView.DrawArrow(pAxMapControl.ActiveView,
                                        new CPoint(dblXAxisStart, dblYAxisStart - 30), new CPoint(dblXAxisStart, dblYAxisEnd), 6, 5); //y arrow; vertical
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "Generalize", dblXAxisStart + 20, dblYAxisEnd + 10, dblTextSize);
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "Time", dblXAxisEnd - 20, dblYAxisStart - 25, dblTextSize);

            //scales
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "", dblXAxisStart - 40, dblMidY00 - dblTextSize / 2, dblTextSize);
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "", dblXAxisStart - 40, dblMidY01 - dblTextSize / 2, dblTextSize);
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "", dblXAxisStart - 40, dblMidY02 - dblTextSize / 2, dblTextSize);
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "", dblXAxisStart - 40, dblMidY03 - dblTextSize / 2, dblTextSize);

            //times
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "2015", dblMidX00, dblYAxisStart - 30, dblTextSize);
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "2016", dblMidX10, dblYAxisStart - 30, dblTextSize);
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "2017", dblMidX20, dblYAxisStart - 30, dblTextSize);
            CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "2018", dblMidX30, dblYAxisStart - 30, dblTextSize);

            var pExportActiveViewCS_Net = new MorphingClass.CCommon.ExportActiveViewCS_Net();

            pExportActiveViewCS_Net.ExportActiveViewParameterized(300, 1, "EMF",
                                                                  pParameterInitialize.strMxdPathBackSlash, strTS, true);


            ////inputs
            //CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "input", dblXAxisStart + 30, dblYAxisStart + 15, dblTextSize);
            //CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "input", dblXAxisStart + 30, oscpl.CptLt[0].Y + 40, dblTextSize);
            //CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "input", nlcpl.CptLt[5].X + 10, dblYAxisStart + 15, dblTextSize);
            //CDrawInActiveView.DrawTextMarker(pAxMapControl.ActiveView, "input", nlcpl.CptLt[5].X + 10, oscpl.CptLt[0].Y + 40, dblTextSize);



            //Output(0.3,0);
            //Output(0, 0.6);
            //Output(0.7, 0.2);
            //Output(0.6, 0.9);
        }
 private void btn010_Click(object sender, EventArgs e)
 {
     _dblProp = 0.1;
     _RelativeInterpolationCpl = CHelpFunc.DisplayInterpolation(_DataRecords, _dblProp);
 }
 private void btnAdd_Click(object sender, EventArgs e)
 {
     _dblProp                  = _dblProp + 0.02;
     pbScale.Value             = Convert.ToInt16(100 * _dblProp);
     _RelativeInterpolationCpl = DisplayInterpolation(_dblProp, _DataRecords.ParameterInitialize.m_mapControl);
 }
 public virtual void btn020_Click(object sender, EventArgs e)
 {
     _dblProp = 0.2;
     _RelativeInterpolationCpl = CDrawInActiveView.DisplayInterpolation(_DataRecords, _dblProp);
 }
 private void btn100_Click(object sender, EventArgs e)
 {
     _dblProp = 1;
     _RelativeInterpolationCpl = DisplayInterpolation(_dblProp, _DataRecords.ParameterInitialize.m_mapControl);
 }
 private void btnInputedScale_Click(object sender, EventArgs e)
 {
     _dblProp = Convert.ToDouble(this.txtProportion.Text);
     _RelativeInterpolationCpl = DisplayInterpolation(_dblProp, _DataRecords.ParameterInitialize.m_mapControl);
 }
 public CMPBBSLDP(CPolyline frcpl, CPolyline tocpl)
 {
     _FromCpl = frcpl;
     _ToCpl   = tocpl;
 }
 private void btn100_Click(object sender, EventArgs e)
 {
     _dblProportion            = 1;
     _RelativeInterpolationCpl = CHelperFunction.DisplayInterpolation(_DataRecords, _dblProportion);
 }
        /// <summary>
        /// 获取线状要素
        /// </summary>
        /// <param name="pDataRecords">数据记录</param>
        /// <param name="dblProp">插值参数</param>
        /// <returns>在处理面状要素时,本程序将原面状要素的边界切开,按线状要素处理,处理完后再重新生成面状要素</returns>
        public CPolyline GetTargetcpl(double dblProp)
        {
            List <CCorrCpts> pCorrCptsLt = _DataRecords.ParameterResult.CCorrCptsLt;   //Read Datasets后,此处ResultPtLt中的对应点为一一对应
            double           dblTX       = _dblTX;

            //统计插值点数
            int intKnownNum   = 0;                            //须固定不参与平差的点的数目
            int intUnknownNum = 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);
                    intKnownNum += 1;
                }
                else
                {
                    intUnknownNum += 1;
                }
            }

            int intUnknownXY = intUnknownNum * 2;   //每个点都有X、Y坐标
            int intPtNum     = pCorrCptsLt.Count;
            int intXYNum     = 2 * intPtNum;


            //找出长度固定的位置(如果一个线段的前后两个点都固定,则该长度固定)
            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 = pCorrCptsLt.Count - 1 - intKnownLengthLt.Count;

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

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

            int intUnknownXYLengthAngle = intUnknownXY + intUnknownLength + intUnknownAngle;

            //定义权重矩阵
            VBMatrix P = new VBMatrix(intUnknownXYLengthAngle, intUnknownXYLengthAngle);

            for (int i = 0; i < intUnknownXY; i++)
            {
                P[i, i] = 1;
            }
            for (int i = 0; i < intUnknownLength; i++)
            {
                P[intUnknownXY + i, intUnknownXY + i] = 100;
            }
            for (int i = 0; i < intUnknownAngle; i++)
            {
                P[intUnknownXY + intUnknownLength + i, intUnknownXY + intUnknownLength + i] = 10000;
            }

            //计算初始值矩阵X0
            VBMatrix X0       = new VBMatrix(intXYNum, 1);
            int      intCount = 0;

            for (int i = 0; i < pCorrCptsLt.Count; i++)
            {
                X0[intCount, 0]     = (1 - dblProp) * pCorrCptsLt[i].FrCpt.X + dblProp * pCorrCptsLt[i].ToCpt.X;
                X0[intCount + 1, 0] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.Y + dblProp * pCorrCptsLt[i].ToCpt.Y;
                intCount           += 2;
            }

            //计算长度初始值(全部计算)
            double[] adblLength0 = new double[intPtNum - 1];
            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);
                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;
            }

            //Xmix里存储了XA和X0的最新混合值
            VBMatrix Xmix = new VBMatrix(intXYNum, 1);

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

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

            for (int i = 0; i < intUnknownNum; i++)
            {
                if (pCorrCptsLt[intSumCount0].FrCpt.isCtrl == false)
                {
                    XA[i * 2, 0]     = X0[intSumCount0 * 2, 0];
                    XA[i * 2 + 1, 0] = X0[intSumCount0 * 2 + 1, 0];
                }
                else
                {
                    i -= 1;
                }
                intSumCount0 += 1;
            }

            //定义系数矩阵(有关长度和角度的值将在循环中给定)
            VBMatrix A = new VBMatrix(intUnknownXYLengthAngle, intUnknownXY);

            for (int i = 0; i < intUnknownXY; i++)
            {
                A[i, i] = 1;
            }

            double dblJudge1         = 0; //该值用于判断是否应该跳出循环
            double dblJudge2         = 0; //该值用于判断是否应该跳出循环
            int    intJudgeIndex     = intUnknownXY / 4;
            int    intIterativeCount = 0;

            double[] adblSubDis  = new double[intPtNum - 1];
            double[] adblAngle   = new double[intPtNum - 2];
            double[] adblAzimuth = new double[intPtNum - 1];
            VBMatrix matl        = new VBMatrix(intUnknownXYLengthAngle, 1);

            do
            {
                int intSumCount1 = 0;
                for (int i = 0; i < intUnknownNum; i++)
                {
                    if (pCorrCptsLt[intSumCount1].FrCpt.isCtrl == false)
                    {
                        matl[2 * i, 0]     = XA[2 * i, 0] - X0[intSumCount1 * 2, 0];
                        matl[2 * i + 1, 0] = XA[2 * i + 1, 0] - X0[intSumCount1 * 2 + 1, 0];
                    }
                    else
                    {
                        i -= 1;
                    }
                    intSumCount1 += 1;
                }

                //计算系数矩阵A第"intUnknownXY"行到"intUnknownXY+intUnknownLength-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;
                }

                //开始计算系数矩阵第"intUnknownXY"行到"intUnknownXY+intUnknownLength-1"行的各元素
                CalADevLength(pCorrCptsLt, intUnknownXY, intUnknownLength, ref A, ref matl, adblSubDis, adblAzimuth, adblLength0);

                //计算系数矩阵A第"intUnknownXY+intUnknownLength"行到"intUnknownXY+intUnknownLength+intUnknownAngle"行的各元素,即角度对各未知数求偏导的值
                CalADevAngle(pCorrCptsLt, intUnknownXY + intUnknownLength, intUnknownAngle, Xmix, ref A, ref matl, adblSubDis, adblAngle, adblAngle0);


                ////计算新的近似值
                //SaveFileDialog SFD = new SaveFileDialog();
                //SFD.ShowDialog();
                //     CHelpFuncExcel.ExportDataToExcelA(A, "maxA", SFD.FileName);
                //CHelpFuncExcel.ExportDataToExcelP(P, "maxP", SFD.FileName);
                //CHelpFuncExcel.ExportDataToExcel2(matl, "maxmatl", SFD.FileName);



                //VBMatrix Temp =A.Trans ()  * P * A;
                //Temp.InvertGaussJordan();
                //XA -= Temp * A.Transpose() * P * matl;

                //平差
                VBMatrix x = InvAtPAAtPmatl(A, P, matl);
                XA -= x;

                //更新Xmix
                int intSumCount4 = 0;
                for (int i = 0; i < intUnknownNum; i++)
                {
                    if (pCorrCptsLt[intSumCount4].FrCpt.isCtrl == false)
                    {
                        Xmix[intSumCount4 * 2, 0]     = XA[i * 2, 0];
                        Xmix[intSumCount4 * 2 + 1, 0] = XA[i * 2 + 1, 0];
                    }
                    else
                    {
                        i -= 1;
                    }
                    intSumCount4 += 1;
                }

                intIterativeCount += 1;
                if (intIterativeCount >= 1000)
                {
                    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];
                CTargetPtLt.Add(cpt);
            }
            CPolyline cpl = new CPolyline(0, CTargetPtLt);

            return(cpl);
        }
        private IEnumerable <CPolyline> GenerateOneSeparateLinkCplEb(CPolyline frcpl, CPolyline tocpl, int intIndex1, int intIndex2, double dblMid, string strDimension)
        {
            CPoint frmidLeftCpt;
            CPoint tomidLeftCpt;
            CPoint frmidRightCpt;
            CPoint tomidRightCpt;

            if (strDimension == "Time")
            {
                frmidLeftCpt  = new CPoint(dblMid, frcpl.CptLt[intIndex1].Y);
                tomidLeftCpt  = new CPoint(dblMid, tocpl.CptLt[intIndex1].Y);
                frmidRightCpt = new CPoint(dblMid, frcpl.CptLt[intIndex2].Y);
                tomidRightCpt = new CPoint(dblMid, tocpl.CptLt[intIndex2].Y);
            }
            else //if (strDimension == "scale")
            {
                frmidLeftCpt  = new CPoint(frcpl.CptLt[intIndex1].X, dblMid);
                tomidLeftCpt  = new CPoint(tocpl.CptLt[intIndex1].X, dblMid);
                frmidRightCpt = new CPoint(frcpl.CptLt[intIndex2].X, dblMid);
                tomidRightCpt = new CPoint(tocpl.CptLt[intIndex2].X, dblMid);
            }

            yield return(new CPolyline(frcpl.CptLt[intIndex1], frmidLeftCpt));

            yield return(new CPolyline(frmidLeftCpt, tomidLeftCpt));

            yield return(new CPolyline(tomidLeftCpt, tocpl.CptLt[intIndex1]));

            yield return(new CPolyline(frcpl.CptLt[intIndex2], frmidRightCpt));

            yield return(new CPolyline(frmidRightCpt, tomidRightCpt));

            yield return(new CPolyline(tomidRightCpt, tocpl.CptLt[intIndex2]));
        }
 public CBSBLGOptCor(CPolyline frcpl, CPolyline tocpl)
 {
     _FromCpl = frcpl;
     _ToCpl   = tocpl;
 }
        //Stopwatch _pstopwatch = new Stopwatch();
        #region Output
        public List <CPolyline> Output(double dblT, double dblS, IRgbColor olIRgbColor, IRgbColor nlIRgbColor, double dblExtraX = 300, double dblExtraY = 300)
        {
            var strTS = _ParameterInitialize.strTS;
            var dblt  = dblT;
            var dbls  = dblS;

            if (strTS == "vario_vario")
            {
            }
            else if (strTS == "vario_separate")
            {
                dbls = SetForSeparate(dblS, 0.5);
            }
            else if (strTS == "separate_vario")
            {
                dblt = SetForSeparate(dblT, 0.5);
            }
            else //if (strTS == "separate_separate")
            {
                dblt = SetForSeparate(dblT, 0.5);
                dbls = SetForSeparate(dblS, 0.5);
            }

            double dblRTime = CGeoFunc.GetInbetweenDbl(olIRgbColor.Red, nlIRgbColor.Red, dblt);
            double dblGTime = CGeoFunc.GetInbetweenDbl(olIRgbColor.Green, nlIRgbColor.Green, dblt);
            double dblBTime = CGeoFunc.GetInbetweenDbl(olIRgbColor.Blue, nlIRgbColor.Blue, dblt);
            int    intRTS   = Convert.ToInt32(CGeoFunc.GetInbetweenDbl(dblRTime, CGeoFunc.GetInbetweenDbl(dblRTime, 255, 0.8), dbls));
            int    intGTS   = Convert.ToInt32(CGeoFunc.GetInbetweenDbl(dblGTime, CGeoFunc.GetInbetweenDbl(dblGTime, 255, 0.8), dbls));
            int    intBTS   = Convert.ToInt32(CGeoFunc.GetInbetweenDbl(dblBTime, CGeoFunc.GetInbetweenDbl(dblBTime, 255, 0.8), dbls));

            var olcpl = _OLCplLt[0];
            var oscpl = _OSCplLt[0];
            var nlcpl = _NLCplLt[0];
            var nscpl = _NSCplLt[0];

            var olcplmoved = olcpl;
            var oscplmoved = oscpl.Move(0, -dblExtraY);
            var nlcplmoved = nlcpl.Move(-dblExtraX, 0);
            var nscplmoved = nscpl.Move(-dblExtraX, -dblExtraY);


            var InterLargerCpl  = CGeoFunc.GetInbetweenCpl(olcplmoved, nlcplmoved, dblt);
            var InterSmallerCpl = CGeoFunc.GetInbetweenCpl(oscplmoved, nscplmoved, dblt);
            var InterCpl        = CGeoFunc.GetInbetweenCpl(InterLargerCpl, InterSmallerCpl, dbls);

            //var simplifedcpllt = CDPSimplify.DPSimplify(CHelpFunc.MakeLt(InterCpl), dblThresholdDis: 300000 * CConstants.dblVerySmallCoord);
            int intPtNum       = olcpl.CptLt.Count - 1;
            var simplifedcpllt = CDPSimplify.DPSimplify(CHelpFunc.MakeLt(InterCpl), dblRemainPoints: intPtNum * ((1 - dbls) * 3 + 1) / 4);

            //var simplifedcptlt = CImaiIriSimplify.ImaiIriSimplify(InterCpl.CptLt, 100000 * CConstants.dblVerySmallCoord).ToList();
            //CDPSimplify.dp
            //CSaveFeature.SaveCpl(InterLargerCpl, "InterLargerCpl_" + dblT.ToString() + " " + dblS.ToString());
            //CSaveFeature.SaveCpl(InterSmallerCpl, "InterSmallerCpl_" + dblT.ToString() + " " + dblS.ToString());
            //CSaveFeature.SaveCpl(InterCpl, "InterCpl_" + dblT.ToString() + " " + dblS.ToString());


            var dblBaseX      = dblT * dblExtraX;
            var dblBaseY      = dblS * dblExtraY;
            var movedInterCpl = new CPolyline(0, CGeoFunc.MoveCptEb(simplifedcpllt[0].CptLt, dblBaseX, dblBaseY).ToList());

            //CSaveFeature.SaveCpl(movedInterCpl, dblT.ToString() + " " + dblS.ToString());
            var movedInterCpg = new CPolygon(movedInterCpl.CptLt);

            CSaveFeature.SaveCpg(movedInterCpg, dblT.ToString() + " " + dblS.ToString(), intRed: intRTS, intGreen: intGTS, intBlue: intBTS);


            var cpbLt = new List <CPolyBase>
            {
                movedInterCpl
            };

            CCreatePointLayer.SavePointLayer(cpbLt, dblT.ToString() + " " + dblS.ToString(), 3);

            return(CHelpFunc.MakeLt(movedInterCpl));



            //var a00 = (1 - x) * (1 - y);    //lower left
            //var a10 = x * (1 - y);          //lower right
            //var a01 = (1 - x) * y;          //upper left
            //var a11 = x * y;                //upper right

            ////var dblDiffX = _NSCplLt[0].CptLt[0].X - _OLCplLt[0].CptLt[0].X;
            ////var dblDiffY = _NSCplLt[0].CptLt[0].Y - _OLCplLt[0].CptLt[0].Y;

            //var dblDiffX = 300;
            //var dblDiffY = 400;

            ////var dblDiffXPlus= dblDiffX+

            //var dblBaseX = dblT * dblDiffX;
            //var dblBaseY = dblS * dblDiffY;
            //var newCplLt = new List<CPolyline>(_OLCplLt.Count);
            //for (int i = 0; i < _OLCplLt.Count; i++)
            //{
            //    var olcpl = _OLCplLt[i];
            //    var oscpl = _OSCplLt[i];
            //    var nlcpl = _NLCplLt[i];
            //    var nscpl = _NSCplLt[i];

            //    var newcptlt = new List<CPoint>(olcpl.CptLt.Count);
            //    for (int j = 0; j < olcpl.CptLt.Count; j++)
            //    {
            //        var dblX = BilinearInterpolateUnit(a00, a10, a01, a11,
            //            olcpl.CptLt[j].X - olcpl.CptLt[j].X, nlcpl.CptLt[j].X - olcpl.CptLt[j].X - dblDiffX,
            //            oscpl.CptLt[j].X - olcpl.CptLt[j].X, nscpl.CptLt[j].X - olcpl.CptLt[j].X - dblDiffX);
            //        var dblY = BilinearInterpolateUnit(a00, a10, a01, a11,
            //            olcpl.CptLt[j].Y - olcpl.CptLt[j].Y, nlcpl.CptLt[j].Y - olcpl.CptLt[j].Y,
            //            oscpl.CptLt[j].Y - olcpl.CptLt[j].Y - dblDiffY, nscpl.CptLt[j].Y - olcpl.CptLt[j].Y - dblDiffY);

            //        newcptlt.Add(new CPoint(j, dblX + dblBaseX + olcpl.CptLt[j].X, dblY + dblBaseY + olcpl.CptLt[j].Y));
            //    }

            //    CImaiIriSimplify.ImaiIriSimplify(newcptlt, CConstants.dblVerySmallCoord);

            //    newCplLt.Add(new CPolyline(i, newcptlt));
            //}

            //CSaveFeature.SaveCplEb(newCplLt, dblT.ToString() + " " + dblS.ToString());
        }
Example #18
0
        /// <summary>
        /// 获取线状要素
        /// </summary>
        /// <param name="pDataRecords">数据记录</param>
        /// <param name="dblProp">插值参数</param>
        /// <returns>在处理面状要素时,本程序将原面状要素的边界切开,按线状要素处理,处理完后再重新生成面状要素</returns>
        public CPolyline GetTargetcpl(double dblProp)
        {
            CParameterResult pParameterResult = _DataRecords.ParameterResult;

            //获取周长
            double dblFrLength = pParameterResult.FromCpl.pPolyline.Length;
            double dblToLength = pParameterResult.ToCpl.pPolyline.Length;


            //确定循环阈值(初始多边形平均边长的千分之一)
            double dblTX = dblFrLength / pParameterResult.FromCpl.CptLt.Count / 1000;

            List <CCorrCpts> pCorrCptsLt = pParameterResult.CCorrCptsLt;   //读取数据后,此处ResultPtLt中的对应点为一一对应
            //pCorrCptsLt[2].FrCpt.isCtrl = false;
            //pCorrCptsLt[2].CorrespondingPtLt[0].FrCpt.isCtrl = false;

            //统计插值点数
            int intKnownNum   = 0;                            //须固定不参与平差的点的数目
            int intUnknownNum = 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);
                    intKnownNum += 1;
                }
                else
                {
                    intUnknownNum += 1;
                }
            }
            int intSumNum    = intKnownNum + intUnknownNum;
            int intUnknownXY = intUnknownNum * 2; //每个点都有X、Y坐标
            int intSumXY     = intSumNum * 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 = pCorrCptsLt.Count - 1 - intKnownLengthLt.Count;

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

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

            int intUnknownXYLengthAngle = intUnknownXY + intUnknownLength + intUnknownAngle;

            //定义权重矩阵
            VBMatrix P = new VBMatrix(intUnknownXYLengthAngle, intUnknownXYLengthAngle);

            for (int i = 0; i < intUnknownXY; i++)
            {
                P[i, i] = 1;
            }
            for (int i = 0; i < intUnknownLength; i++)
            {
                P[intUnknownXY + i, intUnknownXY + i] = 10;
            }
            for (int i = 0; i < intUnknownAngle; i++)
            {
                P[intUnknownXY + intUnknownLength + i, intUnknownXY + intUnknownLength + i] = 100;
            }

            //计算初始值矩阵X0
            VBMatrix X0       = new VBMatrix(intSumXY, 1);
            int      intCount = 0;

            for (int i = 0; i < pCorrCptsLt.Count; i++)
            {
                X0[intCount, 0]     = (1 - dblProp) * pCorrCptsLt[i].FrCpt.X + dblProp * pCorrCptsLt[i].ToCpt.X;
                X0[intCount + 1, 0] = (1 - dblProp) * pCorrCptsLt[i].FrCpt.Y + dblProp * pCorrCptsLt[i].ToCpt.Y;
                intCount           += 2;
            }

            //计算长度初始值(全部计算)
            double[] adblLength0 = new double[intSumNum - 1];
            for (int i = 0; i < pCorrCptsLt.Count - 1; i++)
            {
                double dblfrsublength = Math.Pow((pCorrCptsLt[i + 1].ToCpt.X - pCorrCptsLt[i].ToCpt.X) * (pCorrCptsLt[i + 1].ToCpt.X - pCorrCptsLt[i].ToCpt.X)
                                                 + (pCorrCptsLt[i + 1].ToCpt.Y - pCorrCptsLt[i].ToCpt.Y) * (pCorrCptsLt[i + 1].ToCpt.Y - pCorrCptsLt[i].ToCpt.Y), 0.5);

                double dbltosublength = Math.Pow((pCorrCptsLt[i + 1].ToCpt.X - pCorrCptsLt[i].ToCpt.X) * (pCorrCptsLt[i + 1].ToCpt.X - pCorrCptsLt[i].ToCpt.X)
                                                 + (pCorrCptsLt[i + 1].ToCpt.Y - pCorrCptsLt[i].ToCpt.Y) * (pCorrCptsLt[i + 1].ToCpt.Y - pCorrCptsLt[i].ToCpt.Y), 0.5);
                adblLength0[i] = (1 - dblProp) * dblfrsublength + dblProp * dbltosublength;
            }

            //计算角度初始值(全部计算)
            double[] adblAngle0 = new double[intSumNum - 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;
            }

            //Xmix里存储了XA和X0的最新混合值
            VBMatrix Xmix = new VBMatrix(intSumXY, 1);

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

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

            for (int i = 0; i < intUnknownNum; i++)
            {
                if ((i + intKnownCount) != intKnownLocationLt[intKnownCount])  //当前遍历位置“i + intKnownCount”是否在intKnownLocationLt的位置“intKnownCount”中记录
                {
                    XA[i * 2, 0]     = X0[(i + intKnownCount) * 2, 0];
                    XA[i * 2 + 1, 0] = X0[(i + intKnownCount) * 2 + 1, 0];
                }
                else
                {
                    intKnownCount += 1;
                    i             -= 1;
                }
            }

            //定义系数矩阵(有关长度和角度的值将在循环中给定)
            VBMatrix A = new VBMatrix(intUnknownXYLengthAngle, intUnknownXY);

            for (int i = 0; i < intUnknownXY; i++)
            {
                A[i, i] = 1;
            }

            double dblJudge          = 0; //该值用于判断是否应该跳出循环
            double dblOldJudege      = 0;
            int    intIterativeCount = 0;

            double[] dblSubDis = new double[intSumNum - 1];
            VBMatrix matl      = new VBMatrix(intUnknownXYLengthAngle, 1);

            do
            {
                matl = new VBMatrix(intUnknownXYLengthAngle, 1);
                int intSumCount1 = 0;
                for (int i = 0; i < intUnknownNum; i++)
                {
                    if (pCorrCptsLt[intSumCount1].FrCpt.isCtrl == false)
                    {
                        matl[2 * i, 0]     = XA[2 * i, 0] - X0[intSumCount1 * 2, 0];
                        matl[2 * i + 1, 0] = XA[2 * i + 1, 0] - X0[intSumCount1 * 2 + 1, 0];
                    }
                    else
                    {
                        i -= 1;
                    }
                    intSumCount1 += 1;
                }

                //计算系数矩阵A第"intUnknownXY"行到"intUnknownXY+intUnknownLength-1"行的各元素,即线段长度对各未知数求偏导的值
                //先计算各分母值(注意:分母实际上是求偏导后的一部分值,但却恰好等于两点之间距离,因此其计算公式与距离计算公式相同
                dblSubDis = new double[intSumNum - 1];
                for (int i = 0; i < intSumNum - 1; i++)
                {
                    dblSubDis[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);
                }
                //开始计算系数矩阵第"intUnknownXY"行到"intUnknownXY+intUnknownLength-1"行的各元素
                int intKnownCount2   = 0;
                int intUnKnownCount2 = 0;
                for (int j = 0; j < intUnknownLength; j++)
                {
                    try
                    {
                        int intSumCount = intKnownCount2 + intUnKnownCount2;
                        if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == false && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == false)
                        {
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 0] = (Xmix[2 * intSumCount, 0] - Xmix[2 * intSumCount + 2, 0]) / dblSubDis[intSumCount];
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 1] = (Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 3, 0]) / dblSubDis[intSumCount];
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 2] = -A[intUnknownXY + j, 2 * intUnKnownCount2];
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 3] = -A[intUnknownXY + j, 2 * intUnKnownCount2 + 1];

                            matl[intUnknownXY + j, 0] = dblSubDis[intSumCount] - adblLength0[intSumCount];   //图方便,顺便计算matl

                            intUnKnownCount2 += 1;
                        }
                        else if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == false && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == true)
                        {
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 0] = (Xmix[2 * intSumCount, 0] - Xmix[2 * intSumCount + 2, 0]) / dblSubDis[intSumCount];
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 1] = (Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 3, 0]) / dblSubDis[intSumCount];

                            matl[intUnknownXY + j, 0] = dblSubDis[intSumCount] - adblLength0[intSumCount];   //图方便,顺便计算matl

                            intUnKnownCount2 += 1;
                        }
                        else if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == false)
                        {
                            //注意这种情况,由于"pCorrCptsLt[intSumCount].FrCpt.isCtrl == true"不占位子(即不占列),因此列序号依然为" 2 * intUnKnownCount2 + 0"和" 2 * intUnKnownCount2 + 1",而不是+2,+3
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 0] = -(Xmix[2 * intSumCount, 0] - Xmix[2 * intSumCount + 2, 0]) / dblSubDis[intSumCount];
                            A[intUnknownXY + j, 2 * intUnKnownCount2 + 1] = -(Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 3, 0]) / dblSubDis[intSumCount];

                            matl[intUnknownXY + j, 0] = dblSubDis[intSumCount] - adblLength0[intSumCount];   //图方便,顺便计算matl

                            intKnownCount2 += 1;
                        }
                        else
                        {
                            intKnownCount2 += 1;
                            j -= 1;
                        }
                    }
                    catch (Exception e)
                    {
                        throw;
                    }
                }

                //计算系数矩阵A第"intUnknownXY+intUnknownLength"行到"intUnknownXY+intUnknownLength+intUnknownAngle"行的各元素,即角度对各未知数求偏导的值
                int intKnownCount3     = 0;
                int intUnKnownCount3   = 0;
                int intUnKnownXYLength = intUnknownXY + intUnknownLength;
                for (int j = 0; j < intUnknownAngle; j++)
                {
                    //真是太幸运了,虽然求两向量逆时针夹角时需分多种情况讨论,但各情况的导数形式却是一致的,节省了不少编程精力啊,哈哈
                    int intSumCount = intKnownCount3 + intUnKnownCount3;

                    //常用数据准备
                    double dblA2 = dblSubDis[intSumCount] * dblSubDis[intSumCount];
                    double dblB2 = dblSubDis[intSumCount + 1] * dblSubDis[intSumCount + 1];

                    //开始计算系数值,由于将以下三个情况排列组合将有八种情况,因此按如下方式计算
                    if (pCorrCptsLt[intUnKnownCount3 + intKnownCount3].FrCpt.isCtrl == true && pCorrCptsLt[intUnKnownCount3 + intKnownCount3 + 1].FrCpt.isCtrl == true && pCorrCptsLt[intUnKnownCount3 + intKnownCount3 + 2].FrCpt.isCtrl == true)
                    {
                        intKnownCount3 += 1;
                        j -= 1;
                    }
                    else
                    {
                        double dblNewAngle = CGeoFunc.CalAngle_Counterclockwise(Xmix[2 * intSumCount + 0, 0], Xmix[2 * intSumCount + 1, 0],
                                                                                Xmix[2 * intSumCount + 2, 0], Xmix[2 * intSumCount + 3, 0],
                                                                                Xmix[2 * intSumCount + 4, 0], Xmix[2 * intSumCount + 5, 0]);
                        matl[intUnKnownXYLength + j, 0] = dblNewAngle - adblAngle0[intSumCount];   //图方便,顺便计算matl

                        int intPreTrueNum           = 0;
                        int intUnKnownCount3orginal = intUnKnownCount3;
                        int intKnownCount3orginal   = intKnownCount3;
                        if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3 + 0].FrCpt.isCtrl == false)
                        {
                            A[intUnKnownXYLength + j, 2 * intUnKnownCount3orginal + 0] = -(Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 3, 0]) / dblA2;
                            A[intUnKnownXYLength + j, 2 * intUnKnownCount3orginal + 1] = (Xmix[2 * intSumCount + 0, 0] - Xmix[2 * intSumCount + 2, 0]) / dblA2;

                            intUnKnownCount3 += 1;
                        }
                        else
                        {
                            intPreTrueNum  += 1;
                            intKnownCount3 += 1;
                        }

                        if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3orginal + 1].FrCpt.isCtrl == false)  //注意:对中间点的X、Y求导时,其导数由两部分组成,且为第二部分和第一部分的差
                        {
                            A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 2] = (Xmix[2 * intSumCount + 5, 0] - Xmix[2 * intSumCount + 3, 0]) / dblB2 - (Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 3, 0]) / dblA2;
                            A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 3] = -(Xmix[2 * intSumCount + 4, 0] - Xmix[2 * intSumCount + 2, 0]) / dblB2 + (Xmix[2 * intSumCount + 0, 0] - Xmix[2 * intSumCount + 2, 0]) / dblA2;
                        }
                        else
                        {
                            intPreTrueNum += 1;
                        }
                        if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3orginal + 2].FrCpt.isCtrl == false)
                        {
                            A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 4] = -(Xmix[2 * intSumCount + 5, 0] - Xmix[2 * intSumCount + 3, 0]) / dblB2;
                            A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 5] = (Xmix[2 * intSumCount + 4, 0] - Xmix[2 * intSumCount + 2, 0]) / dblB2;
                        }
                    }
                    #region 用余弦值求夹角,无法判定角度方向,效果不好
                    //int intSumCount = intKnownCount3 + intUnKnownCount3;

                    ////常用数据准备
                    //double dblA2 = dblSubDis[intSumCount] * dblSubDis[intSumCount];
                    //double dblB2 = dblSubDis[intSumCount + 1] * dblSubDis[intSumCount + 1];
                    //double dblAB = dblSubDis[intSumCount] * dblSubDis[intSumCount + 1];
                    //double dblC2 = (Xmix[2 * intSumCount, 0] - Xmix[2 * intSumCount + 4, 0]) * (Xmix[2 * intSumCount, 0] - Xmix[2 * intSumCount + 4, 0])
                    //             + (Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 5, 0]) * (Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 5, 0]);
                    //double dblA2B2mC2 = dblA2 + dblB2 - dblC2;
                    //double dblpart = 1 / Math.Sqrt(4 * dblA2 * dblB2 - dblA2B2mC2 * dblA2B2mC2);

                    ////开始计算系数值,由于将以下三个情况排列组合将有八种情况,因此按如下方式计算
                    //if (pCorrCptsLt[intUnKnownCount3 + intKnownCount3].FrCpt.isCtrl == true && pCorrCptsLt[intUnKnownCount3 + intKnownCount3 + 1].FrCpt.isCtrl == true && pCorrCptsLt[intUnKnownCount3 + intKnownCount3 + 2].FrCpt.isCtrl == true)
                    //{
                    //    intKnownCount3 += 1;
                    //    j -= 1;
                    //}
                    //else
                    //{
                    //    matl[intUnKnownXYLength + j, 0] = Math.Acos(dblA2B2mC2 / 2 / dblAB) - adblAngle0[intSumCount];   //图方便,顺便计算matl

                    //    int intPreTrueNum = 0;
                    //    int intUnKnownCount3orginal = intUnKnownCount3;
                    //    int intKnownCount3orginal = intKnownCount3;
                    //    if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3 + 0].FrCpt.isCtrl == false)
                    //    {
                    //        A[intUnKnownXYLength + j, 2 * intUnKnownCount3orginal + 0] = dblpart * (2 * dblA2 * (Xmix[2 * intSumCount + 2, 0] - Xmix[2 * intSumCount + 4, 0]) + dblA2B2mC2 * (Xmix[2 * intSumCount + 0, 0] - Xmix[2 * intSumCount + 2, 0])) / dblA2;
                    //        A[intUnKnownXYLength + j, 2 * intUnKnownCount3orginal + 1] = dblpart * (2 * dblA2 * (Xmix[2 * intSumCount + 3, 0] - Xmix[2 * intSumCount + 5, 0]) + dblA2B2mC2 * (Xmix[2 * intSumCount + 1, 0] - Xmix[2 * intSumCount + 3, 0])) / dblA2;
                    //        intUnKnownCount3 += 1;
                    //    }
                    //    else
                    //    {
                    //        intPreTrueNum += 1;
                    //        intKnownCount3 += 1;
                    //    }

                    //    if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3orginal + 1].FrCpt.isCtrl == false)
                    //    {
                    //        A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 2] = dblpart * (2 * dblAB * (Xmix[2 * intSumCount + 4, 0] + Xmix[2 * intSumCount + 0, 0] - 2 * Xmix[2 * intSumCount + 2, 0]) + dblA2B2mC2 * (dblB2 * (Xmix[2 * intSumCount + 2, 0] - Xmix[2 * intSumCount + 0, 0]) + dblA2 * (Xmix[2 * intSumCount + 2, 0] - Xmix[2 * intSumCount + 4, 0]))) / dblAB;
                    //        A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 3] = dblpart * (2 * dblAB * (Xmix[2 * intSumCount + 5, 0] + Xmix[2 * intSumCount + 1, 0] - 2 * Xmix[2 * intSumCount + 3, 0]) + dblA2B2mC2 * (dblB2 * (Xmix[2 * intSumCount + 3, 0] - Xmix[2 * intSumCount + 1, 0]) + dblA2 * (Xmix[2 * intSumCount + 3, 0] - Xmix[2 * intSumCount + 5, 0]))) / dblAB;
                    //    }
                    //    else
                    //    {
                    //        intPreTrueNum += 1;
                    //    }
                    //    if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3orginal + 2].FrCpt.isCtrl == false)
                    //    {
                    //        A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 4] = dblpart * (2 * dblB2 * (Xmix[2 * intSumCount + 2, 0] - Xmix[2 * intSumCount + 0, 0]) + dblA2B2mC2 * (Xmix[2 * intSumCount + 4, 0] - Xmix[2 * intSumCount + 2, 0])) / dblB2;
                    //        A[intUnKnownXYLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 5] = dblpart * (2 * dblA2 * (Xmix[2 * intSumCount + 3, 0] - Xmix[2 * intSumCount + 1, 0]) + dblA2B2mC2 * (Xmix[2 * intSumCount + 5, 0] - Xmix[2 * intSumCount + 3, 0])) / dblB2;
                    //    }
                    //}
                    #endregion
                }



                //记录一个值以协助判断是否可以退出循环
                double dblLast = XA[0, 0];

                ////计算新的近似值
                //SaveFileDialog SFD = new SaveFileDialog();
                //SFD.ShowDialog();
                //     CHelpFuncExcel.ExportDataToExcelA(A, "maxA", SFD.FileName);
                //CHelpFuncExcel.ExportDataToExcelP(P, "maxP", SFD.FileName);
                //CHelpFuncExcel.ExportDataToExcel2(matl, "maxmatl", SFD.FileName);



                //VBMatrix Temp =A.Trans ()  * P * A;
                //Temp.InvertGaussJordan();
                //XA -= Temp * A.Transpose() * P * matl;

                XA -= InvAtPAAtPmatl(A, P, matl);

                //更新Xmix和matl
                int intKnownCount4 = 0;
                for (int i = 0; i < intUnknownNum; i++)
                {
                    if ((i + intKnownCount4) != intKnownLocationLt[intKnownCount4])
                    {
                        Xmix[(i + intKnownCount4) * 2, 0]     = XA[i * 2, 0];
                        Xmix[(i + intKnownCount4) * 2 + 1, 0] = XA[i * 2 + 1, 0];
                    }
                    else
                    {
                        intKnownCount4 += 1;
                        i -= 1;
                    }
                }

                dblJudge           = Math.Abs(dblLast - XA[0, 0]);
                intIterativeCount += 1;
                if (intIterativeCount >= 10000)
                {
                    break;
                }
                if (dblOldJudege == dblJudge)
                {
                    break;
                }

                dblOldJudege = dblJudge;
            } while (dblJudge > dblTX);

            //生成目标线段
            List <CPoint> CTargetPtLt = new List <CPoint>();
            for (int i = 0; i < intSumNum; i++)
            {
                CPoint cpt = new CPoint(i);
                cpt.X = Xmix[2 * i, 0];
                cpt.Y = Xmix[2 * i + 1, 0];
                CTargetPtLt.Add(cpt);
            }
            CPolyline cpl = new CPolyline(0, CTargetPtLt);
            return(cpl);
        }
 private void btnAdd_Click(object sender, EventArgs e)
 {
     _dblProp                  = _dblProp + 0.02;
     pbScale.Value             = Convert.ToInt16(100 * _dblProp);
     _RelativeInterpolationCpl = CHelpFunc.DisplayInterpolation(_DataRecords, _dblProp);
 }
Example #20
0
        /// <summary>
        /// 获取线状要素
        /// </summary>
        /// <param name="intInterNum">Inter: Interpolation</param>
        /// <returns>在处理面状要素时,本程序将原面状要素的边界切开,按线状要素处理,处理完后再重新生成面状要素</returns>
        public List <CPolyline> GetTargetcpllt()
        {
            int intIterationNum          = Convert.ToInt32(_DataRecords.ParameterInitialize.txtIterationNum.Text);
            int intInterNum              = Convert.ToInt32(_DataRecords.ParameterInitialize.txtInterpolationNum.Text);
            List <CCorrCpts> pCorrCptsLt = _DataRecords.ParameterResult.CCorrCptsLt;   //读取数据后,此处ResultPtLt中的对应点为一一对应
            double           dblTX       = _dblTX;
            double           dblInterval = 1 / Convert.ToDouble(intInterNum + 1);


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


            //计算长度初始值(全部计算)
            double[,] adblLength0 = new double[intInterNum, intPtNum - 1];
            double[,] adblLength  = new double[intInterNum, intPtNum - 1];  //顺便定义中间值数组
            for (int j = 0; j < pCorrCptsLt.Count - 1; j++)
            {
                double dblfrsublength = CGeoFunc.CalDis(pCorrCptsLt[j + 1].FrCpt, pCorrCptsLt[j].FrCpt);
                double dbltosublength = CGeoFunc.CalDis(pCorrCptsLt[j + 1].ToCpt, pCorrCptsLt[j].ToCpt);
                for (int i = 0; i < intInterNum; i++)
                {
                    double dblProp = (i + 1) * dblInterval;
                    adblLength0[i, j] = (1 - dblProp) * dblfrsublength + dblProp * dbltosublength;
                }
                //pCorrCptsLt[j].FrCpt.isCtrl = false;  //仅以最开始两对和最终两队对应点为固定点,故此先设置为false
            }

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

                //角度初始值
                for (int i = 0; i < intInterNum; i++)
                {
                    double dblProp = (i + 1) * dblInterval;
                    adblAngle0[i, j] = (1 - dblProp) * dblfrAngle + dblProp * dbltoAngle;
                }
            }

            //多线段间对应顶点距离初始值(全部计算),全部设置为0
            //目标值也设置为0
            double[,] adblIntervalDis0 = new double[intInterNum + 1, intPtNum];
            double[,] adblIntervalDis  = new double[intInterNum + 1, intPtNum];  //顺便定义中间值数组
            for (int j = 0; j < pCorrCptsLt.Count; j++)
            {
                //长度初始值
                for (int i = 0; i <= intInterNum; i++)
                {
                    adblIntervalDis0[i, j] = 0;
                    adblIntervalDis[i, j]  = 0;
                }
            }


            //计算坐标初始值,以及各线段方位角初始值
            //注意:默认固定第一条边
            pCorrCptsLt[0].FrCpt.isCtrl = true;
            pCorrCptsLt[1].FrCpt.isCtrl = true;
            VBMatrix X0 = new VBMatrix(intMultiXYNum, 1);

            double[,] adblAzimuth = new double[intInterNum, intPtNum - 1];
            for (int i = 0; i < intInterNum; i++)
            {
                double dblProp  = (i + 1) * dblInterval;
                double dblnewX0 = (1 - dblProp) * pCorrCptsLt[0].FrCpt.X + dblProp * pCorrCptsLt[0].ToCpt.X;
                double dblnewY0 = (1 - dblProp) * pCorrCptsLt[0].FrCpt.Y + dblProp * pCorrCptsLt[0].ToCpt.Y;
                double dblnewX1 = (1 - dblProp) * pCorrCptsLt[1].FrCpt.X + dblProp * pCorrCptsLt[1].ToCpt.X;
                double dblnewY1 = (1 - dblProp) * pCorrCptsLt[1].FrCpt.Y + dblProp * pCorrCptsLt[1].ToCpt.Y;
                adblAzimuth[i, 0] = CGeoFunc.CalAxisAngle(dblnewX0, dblnewY0, dblnewX1, dblnewY1);

                int intBasicIndex = i * intXYNum;
                X0[intBasicIndex + 0, 0] = dblnewX0;
                X0[intBasicIndex + 1, 0] = dblnewY0;
                X0[intBasicIndex + 2, 0] = dblnewX1;
                X0[intBasicIndex + 3, 0] = dblnewY1;
            }

            //其它点
            //是否固定最后两个点
            pCorrCptsLt[pCorrCptsLt.Count - 2].FrCpt.isCtrl = true;
            pCorrCptsLt[pCorrCptsLt.Count - 1].FrCpt.isCtrl = true;

            for (int j = 2; j < intPtNum; j++)
            {
                for (int i = 0; i < intInterNum; i++)
                {
                    int    intBasicIndexIJ = i * intXYNum + 2 * j;
                    double dblProp         = (i + 1) * dblInterval;
                    X0[intBasicIndexIJ + 0, 0] = (1 - dblProp) * pCorrCptsLt[j].FrCpt.X + dblProp * pCorrCptsLt[j].ToCpt.X;
                    X0[intBasicIndexIJ + 1, 0] = (1 - dblProp) * pCorrCptsLt[j].FrCpt.Y + dblProp * pCorrCptsLt[j].ToCpt.Y;
                    double dblAngle = CGeoFunc.CalAngle_Counterclockwise(X0[intBasicIndexIJ - 4, 0], X0[intBasicIndexIJ - 3, 0], X0[intBasicIndexIJ - 2, 0], X0[intBasicIndexIJ - 1, 0], X0[intBasicIndexIJ - 0, 0], X0[intBasicIndexIJ + 1, 0]);  //计算实际夹角
                    adblAzimuth[i, j - 1] = adblAzimuth[i, j - 2] + dblAngle - Math.PI;
                }
            }


            //for (int j = 2; j < intPtNum; j++)
            //{

            //    if (pCorrCptsLt[j].FrCpt.isCtrl == false)
            //    {
            //        for (int i = 0; i < intInterNum; i++)
            //        {
            //            int intBasicIndexI = i * intXYNum;
            //            adblAzimuth[i, j - 1] = adblAzimuth[i, j - 2] + adblAngle0[i, j - 2] - Math.PI;
            //            X0[intBasicIndexI + 2 * j + 0, 0] = X0[intBasicIndexI + 2 * (j - 1) + 0, 0] + adblLength0[i, j - 1] * Math.Cos(adblAzimuth[i, j - 1]);
            //            X0[intBasicIndexI + 2 * j + 1, 0] = X0[intBasicIndexI + 2 * (j - 1) + 1, 0] + adblLength0[i, j - 1] * Math.Sin(adblAzimuth[i, j - 1]);
            //        }
            //    }
            //    else
            //    {
            //        for (int i = 0; i < intInterNum; i++)
            //        {
            //            int intBasicIndexIJ = i * intXYNum + 2 * j;
            //            double dblProp = (i + 1) * dblInterval;
            //            X0[intBasicIndexIJ + 0, 0] = (1 - dblProp) * pCorrCptsLt[j].FrCpt.X + dblProp * pCorrCptsLt[j].ToCpt.X;
            //            X0[intBasicIndexIJ + 1, 0] = (1 - dblProp) * pCorrCptsLt[j].FrCpt.Y + dblProp * pCorrCptsLt[j].ToCpt.Y;
            //            double dblAngle = CGeoFunc.CalAngle_Counterclockwise(X0[intBasicIndexIJ - 4, 0], X0[intBasicIndexIJ - 3, 0], X0[intBasicIndexIJ - 2, 0], X0[intBasicIndexIJ - 1, 0], X0[intBasicIndexIJ - 0, 0], X0[intBasicIndexIJ + 1, 0]);  //计算实际夹角
            //            adblAzimuth[i, j - 1] = adblAzimuth[i, j - 2] + dblAngle - Math.PI;
            //        }
            //    }
            //}


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

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

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

            //找出长度固定的位置(如果一个线段的前后两个点都固定,则该长度固定)。另外,长度固定则该边的方位角也固定
            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 intMultiUnknownLength      = intInterNum * intUnknownLength;
            int intMultiUnknownAngle       = intInterNum * intUnknownAngle;
            int intMultiUnknownLengthAngle = intMultiUnknownLength + intMultiUnknownAngle;
            int intMultiUnknownInterval    = (intInterNum + 1) * intUnknownPt;
            int intSumConstraints          = intMultiUnknownLength + intMultiUnknownAngle + intMultiUnknownInterval;

            //定义权重矩阵
            VBMatrix P = new VBMatrix(intSumConstraints, intSumConstraints);

            for (int i = 0; i < intMultiUnknownLength; i++)  //长度权重
            {
                P[i, i] = 1;
            }
            for (int i = 0; i < intMultiUnknownAngle; i++)   //角度权重
            {
                P[intMultiUnknownLength + i, intMultiUnknownLength + i] = 40;
            }
            for (int i = 0; i < intMultiUnknownInterval; i++)   //角度权重
            {
                P[intMultiUnknownLengthAngle + i, intMultiUnknownLengthAngle + i] = 10000000000000;
            }



            //for (int i = 0; i < intInterNum; i++)
            //{
            //    int intBasicIndex2 = i * intUnknownLengthAngle;
            //    for (int j = 0; j < intUnknownLength; j++)
            //    {
            //        P[intBasicIndex2 + j, intBasicIndex2 + j] = 1;
            //    }
            //    for (int j = 0; j < intUnknownAngle; j++)
            //    {
            //        P[intBasicIndex2 + intUnknownLength + j, intBasicIndex2 + intUnknownLength + j] = 1;
            //    }
            //}

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

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

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

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

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

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

            for (int k = 0; k < 2; k++)
            {
                //break;
                do
                {
                    if (intIterativeCount >= intIterationNum)
                    {
                        break;
                    }
                    intIterativeCount += 1;


                    VBMatrix matl = new VBMatrix(intSumConstraints, 1);


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

                    //计算新的方位角
                    for (int i = 0; i < intInterNum; i++)
                    {
                        int intBasicIndexA1 = i * intXYNum;
                        //第一条线段的方位角
                        adblAzimuth[i, 0] = CGeoFunc.CalAxisAngle(Xmix[intBasicIndexA1 + 0, 0], Xmix[intBasicIndexA1 + 1, 0], Xmix[intBasicIndexA1 + 2, 0], Xmix[intBasicIndexA1 + 3, 0]);
                        //后面线段的方位角
                        for (int j = 1; j < intPtNum - 1; j++)
                        {
                            int    intBasicIndexIJA1 = intBasicIndexA1 + 2 * j;
                            double dblAngle          = CGeoFunc.CalAngle_Counterclockwise(Xmix[intBasicIndexIJA1 - 2, 0], Xmix[intBasicIndexIJA1 - 1, 0],
                                                                                          Xmix[intBasicIndexIJA1 + 0, 0], Xmix[intBasicIndexIJA1 + 1, 0],
                                                                                          Xmix[intBasicIndexIJA1 + 2, 0], Xmix[intBasicIndexIJA1 + 3, 0]);
                            adblAzimuth[i, j] = adblAzimuth[i, j - 1] + dblAngle - Math.PI;
                        }
                    }

                    //计算新的多线段间对应顶点距离
                    for (int j = 0; j < intPtNum; j++)
                    {
                        int int2J = 2 * j;
                        //源线段与第一生成线段间对应点距离
                        adblIntervalDis[0, j] = Math.Sqrt((pCorrCptsLt[j].FrCpt.X - Xmix[int2J + 0, 0]) * (pCorrCptsLt[j].FrCpt.X - Xmix[int2J + 0, 0]) +
                                                          (pCorrCptsLt[j].FrCpt.Y - Xmix[int2J + 1, 0]) * (pCorrCptsLt[j].FrCpt.Y - Xmix[int2J + 1, 0]));
                        //目标线段与最后生成线段间对应点距离
                        adblIntervalDis[intInterNum, j] = Math.Sqrt((pCorrCptsLt[j].ToCpt.X - Xmix[(intInterNum - 1) * intXYNum + int2J + 0, 0]) * (pCorrCptsLt[j].ToCpt.X - Xmix[(intInterNum - 1) * intXYNum + int2J + 0, 0]) +
                                                                    (pCorrCptsLt[j].ToCpt.Y - Xmix[(intInterNum - 1) * intXYNum + int2J + 1, 0]) * (pCorrCptsLt[j].ToCpt.Y - Xmix[(intInterNum - 1) * intXYNum + int2J + 1, 0]));
                        //各生成线段间对应点距离
                        for (int i = 1; i < intInterNum; i++)
                        {
                            adblIntervalDis[i, j] = Math.Sqrt((Xmix[(i - 1) * intXYNum + int2J + 0, 0] - Xmix[i * intXYNum + int2J + 0, 0]) * (Xmix[(i - 1) * intXYNum + int2J + 0, 0] - Xmix[i * intXYNum + int2J + 0, 0]) +
                                                              (Xmix[(i - 1) * intXYNum + int2J + 1, 0] - Xmix[i * intXYNum + int2J + 1, 0]) * (Xmix[(i - 1) * intXYNum + int2J + 1, 0] - Xmix[i * intXYNum + int2J + 1, 0]));
                        }
                    }

                    //计算系数矩阵中关于长度值的导数部分(注意:隐含的距离计算公式为后一个点的坐标减前一个点的坐标)
                    int intKnownCount2   = 0;
                    int intUnKnownCount2 = 0;
                    for (int j = 0; j < intUnknownLength; j++)
                    {
                        int intSumCount     = intKnownCount2 + intUnKnownCount2;
                        int intBasicIndexL2 = 2 * intUnKnownCount2;
                        if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == false && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == false)
                        {
                            for (int i = 0; i < intInterNum; i++)
                            {
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 0] = -Math.Cos(adblAzimuth[i, intSumCount]);
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 1] = -Math.Sin(adblAzimuth[i, intSumCount]);
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 2] = -A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 0];
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 3] = -A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 1];

                                matl[i * intUnknownLength + j, 0] = adblLength0[i, intSumCount] - adblLength[i, intSumCount];   //图方便,顺便计算matl
                            }
                            intUnKnownCount2 += 1;
                        }
                        else if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == false && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == true)
                        {
                            for (int i = 0; i < intInterNum; i++)
                            {
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 0] = -Math.Cos(adblAzimuth[i, intSumCount]);
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 1] = -Math.Sin(adblAzimuth[i, intSumCount]);

                                matl[i * intUnknownLength + j, 0] = adblLength0[i, intSumCount] - adblLength[i, intSumCount];   //图方便,顺便计算matl
                            }
                            intUnKnownCount2 += 1;
                        }
                        else if (pCorrCptsLt[intSumCount].FrCpt.isCtrl == true && pCorrCptsLt[intSumCount + 1].FrCpt.isCtrl == false)
                        {
                            for (int i = 0; i < intInterNum; i++)
                            {
                                //注意这种情况,由于"pCorrCptsLt[intSumCount].FrCpt.isCtrl == true"不占位子(即不占列),因此列序号依然为" 2 * intUnKnownCount + 0"和" 2 * intUnKnownCount + 1",而不是+2,+3
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 0] = Math.Cos(adblAzimuth[i, intSumCount]);
                                A[i * intUnknownLength + j, i *intUnknownXY + intBasicIndexL2 + 1] = Math.Sin(adblAzimuth[i, intSumCount]);

                                matl[i * intUnknownLength + j, 0] = adblLength0[i, intSumCount] - adblLength[i, intSumCount];   //图方便,顺便计算matl
                            }
                            intKnownCount2 += 1;
                        }
                        else
                        {
                            intKnownCount2 += 1;
                            j -= 1;
                        }
                    }

                    //计算系数矩阵中关于夹角值的导数部分
                    int intKnownCount3   = 0;
                    int intUnKnownCount3 = 0;
                    for (int j = 0; j < intUnknownAngle; j++)
                    {
                        //真是太幸运了,虽然求两向量逆时针夹角时需分多种情况讨论,但各情况的导数形式却是一致的,节省了不少编程精力啊,哈哈
                        int intSumCount = intKnownCount3 + intUnKnownCount3;


                        //常用数据准备
                        double[] adblA2 = new double[intInterNum];
                        double[] adblB2 = new double[intInterNum];
                        for (int i = 0; i < intInterNum; i++)
                        {
                            adblA2[i] = adblLength[i, intSumCount + 0] * adblLength[i, intSumCount + 0];
                            adblB2[i] = adblLength[i, intSumCount + 1] * adblLength[i, intSumCount + 1];
                        }

                        //开始计算系数值,由于将以下三个情况排列组合将有八种情况,因此按如下方式计算
                        if (pCorrCptsLt[intUnKnownCount3 + intKnownCount3].FrCpt.isCtrl == true && pCorrCptsLt[intUnKnownCount3 + intKnownCount3 + 1].FrCpt.isCtrl == true && pCorrCptsLt[intUnKnownCount3 + intKnownCount3 + 2].FrCpt.isCtrl == true)
                        {
                            intKnownCount3 += 1;
                            j -= 1;
                        }
                        else
                        {
                            for (int i = 0; i < intInterNum; i++)
                            {
                                int    intBasicIndexFi3 = i * intXYNum + 2 * intSumCount;
                                double dblNewAngle      = CGeoFunc.CalAngle_Counterclockwise(Xmix[intBasicIndexFi3 + 0, 0], Xmix[intBasicIndexFi3 + 1, 0],
                                                                                             Xmix[intBasicIndexFi3 + 2, 0], Xmix[intBasicIndexFi3 + 3, 0],
                                                                                             Xmix[intBasicIndexFi3 + 4, 0], Xmix[intBasicIndexFi3 + 5, 0]);

                                adblAngle[i, j] = dblNewAngle;
                                matl[intMultiUnknownLength + i * intUnknownAngle + j, 0] = adblAngle0[i, intSumCount] - dblNewAngle;      //图方便,顺便计算matl
                            }

                            int intPreTrueNum           = 0;
                            int intUnKnownCount3orginal = intUnKnownCount3;
                            int intKnownCount3orginal   = intKnownCount3;
                            if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3orginal + 0].FrCpt.isCtrl == false)
                            {
                                //X1,Y1的导数值(注意:该部分是减数,因此值为导数的负数)
                                for (int i = 0; i < intInterNum; i++)
                                {
                                    A[intMultiUnknownLength + i * intUnknownAngle + j, i *intUnknownXY + 2 * intUnKnownCount3orginal + 0] = -(Xmix[i * intXYNum + 2 * intSumCount + 3, 0] - Xmix[i * intXYNum + 2 * intSumCount + 1, 0]) / adblA2[i];
                                    A[intMultiUnknownLength + i * intUnknownAngle + j, i *intUnknownXY + 2 * intUnKnownCount3orginal + 1] = (Xmix[i * intXYNum + 2 * intSumCount + 2, 0] - Xmix[i * intXYNum + 2 * intSumCount + 0, 0]) / adblA2[i];
                                }

                                intUnKnownCount3 += 1;
                            }
                            else
                            {
                                intPreTrueNum  += 1;
                                intKnownCount3 += 1;
                            }

                            if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3orginal + 1].FrCpt.isCtrl == false)
                            {
                                //X2,Y2的导数值
                                for (int i = 0; i < intInterNum; i++)
                                {
                                    A[intMultiUnknownLength + i * intUnknownAngle + j, i *intUnknownXY + 2 * (intUnKnownCount3orginal - intPreTrueNum) + 2] = (Xmix[i * intXYNum + 2 * intSumCount + 5, 0] - Xmix[i * intXYNum + 2 * intSumCount + 3, 0]) / adblB2[i]
                                                                                                                                                              + (Xmix[i * intXYNum + 2 * intSumCount + 3, 0] - Xmix[i * intXYNum + 2 * intSumCount + 1, 0]) / adblA2[i];
                                    A[intMultiUnknownLength + i * intUnknownAngle + j, i *intUnknownXY + 2 * (intUnKnownCount3orginal - intPreTrueNum) + 3] = -(Xmix[i * intXYNum + 2 * intSumCount + 4, 0] - Xmix[i * intXYNum + 2 * intSumCount + 2, 0]) / adblB2[i]
                                                                                                                                                              - (Xmix[i * intXYNum + 2 * intSumCount + 2, 0] - Xmix[i * intXYNum + 2 * intSumCount + 0, 0]) / adblA2[i];
                                }
                            }
                            else
                            {
                                intPreTrueNum += 1;
                            }
                            if (pCorrCptsLt[intUnKnownCount3orginal + intKnownCount3orginal + 2].FrCpt.isCtrl == false)
                            {
                                //X3,Y3的导数值
                                for (int i = 0; i < intInterNum; i++)
                                {
                                    A[intMultiUnknownLength + i * intUnknownAngle + j, i *intUnknownXY + 2 * (intUnKnownCount3orginal - intPreTrueNum) + 4] = -(Xmix[i * intXYNum + 2 * intSumCount + 5, 0] - Xmix[i * intXYNum + 2 * intSumCount + 3, 0]) / adblB2[i];
                                    A[intMultiUnknownLength + i * intUnknownAngle + j, i *intUnknownXY + 2 * (intUnKnownCount3orginal - intPreTrueNum) + 5] = (Xmix[i * intXYNum + 2 * intSumCount + 4, 0] - Xmix[i * intXYNum + 2 * intSumCount + 2, 0]) / adblB2[i];
                                }
                            }
                        }
                    }

                    //计算系数矩阵中关于多线段间对应顶点距离的导数部分(注意:隐含的距离计算公式为后一个点的坐标减前一个点的坐标)
                    int intKnownCount4   = 0;
                    int intUnKnownCount4 = 0;
                    for (int j = 0; j < intUnknownPt; j++)
                    {
                        int intSumCount4    = intKnownCount4 + intUnKnownCount4;
                        int intBasicIndexL4 = 2 * intUnKnownCount4;
                        if (pCorrCptsLt[intSumCount4].FrCpt.isCtrl == false)
                        {
                            int l = 0;
                            //源线段与第一生成线段间对应点距离导数
                            A[intMultiUnknownLengthAngle + l * intUnknownPt + j, (l - 0) * intUnknownXY + intBasicIndexL4 + 0] = (Xmix[l * intXYNum + 2 * intSumCount4 + 0, 0] - pCorrCptsLt[intSumCount4].FrCpt.X) / adblIntervalDis[l, intSumCount4];
                            A[intMultiUnknownLengthAngle + l * intUnknownPt + j, (l - 0) * intUnknownXY + intBasicIndexL4 + 1] = (Xmix[l * intXYNum + 2 * intSumCount4 + 1, 0] - pCorrCptsLt[intSumCount4].FrCpt.Y) / adblIntervalDis[l, intSumCount4];

                            matl[intMultiUnknownLengthAngle + l * intUnknownPt + j, 0] = adblIntervalDis0[l, intSumCount4] - adblIntervalDis[l, intSumCount4];      //图方便,顺便计算matl

                            //最后生成线段与目标线段间对应点距离导数
                            l = intInterNum;
                            A[intMultiUnknownLengthAngle + l * intUnknownPt + j, (l - 1) * intUnknownXY + intBasicIndexL4 + 0] = -(pCorrCptsLt[intSumCount4].ToCpt.X - Xmix[(l - 1) * intXYNum + 2 * intSumCount4 + 0, 0]) / adblIntervalDis[l, intSumCount4];
                            A[intMultiUnknownLengthAngle + l * intUnknownPt + j, (l - 1) * intUnknownXY + intBasicIndexL4 + 1] = -(pCorrCptsLt[intSumCount4].ToCpt.Y - Xmix[(l - 1) * intXYNum + 2 * intSumCount4 + 1, 0]) / adblIntervalDis[l, intSumCount4];

                            matl[intMultiUnknownLengthAngle + l * intUnknownPt + j, 0] = adblIntervalDis0[l, intSumCount4] - adblIntervalDis[l, intSumCount4];       //图方便,顺便计算matl

                            //各生成线段间对应点距离导数
                            for (int i = 1; i < intInterNum; i++)
                            {
                                A[intMultiUnknownLengthAngle + i * intUnknownPt + j, (i - 1) * intUnknownXY + intBasicIndexL4 + 0] = -(Xmix[i * intXYNum + 2 * intSumCount4 + 0, 0] - Xmix[(i - 1) * intXYNum + 2 * intSumCount4 + 0, 0]) / adblIntervalDis[i, intSumCount4];
                                A[intMultiUnknownLengthAngle + i * intUnknownPt + j, (i - 1) * intUnknownXY + intBasicIndexL4 + 1] = -(Xmix[i * intXYNum + 2 * intSumCount4 + 1, 0] - Xmix[(i - 1) * intXYNum + 2 * intSumCount4 + 1, 0]) / adblIntervalDis[i, intSumCount4];
                                A[intMultiUnknownLengthAngle + i * intUnknownPt + j, (i - 0) * intUnknownXY + intBasicIndexL4 + 0] = -A[intMultiUnknownLengthAngle + i * intUnknownPt + j, (i - 1) * intUnknownXY + +intBasicIndexL4 + 0];
                                A[intMultiUnknownLengthAngle + i * intUnknownPt + j, (i - 0) * intUnknownXY + intBasicIndexL4 + 1] = -A[intMultiUnknownLengthAngle + i * intUnknownPt + j, (i - 1) * intUnknownXY + +intBasicIndexL4 + 1];

                                matl[intMultiUnknownLengthAngle + i * intUnknownPt + j, 0] = adblIntervalDis0[i, intSumCount4] - adblIntervalDis[i, intSumCount4];      //图方便,顺便计算matl
                                //double dblIntervalDis = adblIntervalDis[i, intSumCount4];
                                //double dblIntervalDis0 = adblIntervalDis0[i, intSumCount4];
                                //double dblmatl = dblIntervalDis - dblIntervalDis0;
                                //double ttt = 6;
                            }

                            intUnKnownCount4 += 1;
                        }
                        else
                        {
                            intKnownCount4 += 1;
                            j -= 1;
                        }
                    }



                    int tt = 5;

                    //CHelpFuncExcel.ExportDataToExcel2(A, "matA", _DataRecords.ParameterInitialize.strSavePath);
                    //CHelpFuncExcel.ExportDataToExcelP(P, "matP", _DataRecords.ParameterInitialize.strSavePath);
                    //CHelpFuncExcel.ExportDataToExcel2(matl, "matmatl", _DataRecords.ParameterInitialize.strSavePath);



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

                    XA += x;


                    //CHelpFuncExcel.ExportDataToExcel2(XA, "matXA", _DataRecords.ParameterInitialize.strSavePath);

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

                    _DataRecords.ParameterInitialize.txtVtPV.Text = "   VtPV = " + dblVtPV.ToString();


                    //VBMatrix L = new VBMatrix(intSumConstraints, 1);
                    //for (int i = 0; i < intInterNum; i++)
                    //{
                    //    for (int j = 0; j < intUnknownLength; j++)
                    //    {
                    //        L[i * intUnknownLength + j, 0] = adblLength[i, j];
                    //    }

                    //    for (int j = 0; j < intUnknownAngle; j++)
                    //    {
                    //        L[intInterNum * intUnknownLength + i * intUnknownAngle + j, 0] = adblAngle[i, j];
                    //    }
                    //}
                    //for (int i = 0; i <= intInterNum; i++)
                    //{
                    //    for (int j = 0; j < intUnknownPt; j++)
                    //    {
                    //        L[intInterNum * intUnknownLengthAngle + i * intUnknownPt + j, 0] = adblIntervalDis[i, j];
                    //    }
                    //}


                    //VBMatrix LPlusV = L + V;
                    //VBMatrix AX = A * XA;

                    //CHelpFuncExcel.ExportDataToExcel2(LPlusV, "matLPlusV", _DataRecords.ParameterInitialize.strSavePath);
                    //CHelpFuncExcel.ExportDataToExcel2(AX, "matAX", _DataRecords.ParameterInitialize.strSavePath);



                    //更新Xmix
                    int intSumCount5 = 0;
                    for (int j = 0; j < intUnknownPt; j++)
                    {
                        if (pCorrCptsLt[intSumCount5].FrCpt.isCtrl == false)
                        {
                            for (int i = 0; i < intInterNum; i++)
                            {
                                Xmix[i * intXYNum + intSumCount5 * 2 + 0, 0] = XA[i * intUnknownXY + j * 2 + 0, 0];
                                Xmix[i * intXYNum + intSumCount5 * 2 + 1, 0] = XA[i * intUnknownXY + j * 2 + 1, 0];
                            }
                        }
                        else
                        {
                            j -= 1;
                        }
                        intSumCount5 += 1;
                    }



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

                    //} while ((dblJudge1 > dblTX) || (dblJudge2 > dblTX) || (dblJudge3 > dblTX));
                }while ((dblJudge1 >= 0) || (dblJudge2 >= 0) || (dblJudge3 >= 0));
                break;



                for (int i = 0; i < intMultiUnknownLength; i++)  //长度权重
                {
                    P[i, i] = 1;
                }
                for (int i = 0; i < intMultiUnknownAngle; i++)   //角度权重
                {
                    P[intMultiUnknownLength + i, intMultiUnknownLength + i] = 39.48;
                }
                for (int i = 0; i < intMultiUnknownInterval; i++)   //角度权重
                {
                    P[intMultiUnknownLengthAngle + i, intMultiUnknownLengthAngle + i] = 1;
                }
            }


            //生成目标线段
            List <CPolyline> cpllt = new List <CPolyline>();

            for (int i = 0; i < intInterNum; i++)
            {
                List <CPoint> cptlt = new List <CPoint>();
                for (int j = 0; j < intPtNum; j++)
                {
                    CPoint cpt = new CPoint(j, Xmix[i * intXYNum + j * 2, 0], Xmix[i * intXYNum + j * 2 + 1, 0]);
                    cptlt.Add(cpt);
                }
                CPolyline cpl = new CPolyline(i, cptlt);
                cpllt.Add(cpl);
            }

            return(cpllt);
        }
        /// <summary>创建T矩阵</summary>
        /// <param name="frcpl">大比例尺线状要素</param>
        /// <param name="tocpl">小比例尺线状要素</param>
        /// <param name="CFrEdgeLt">大比例尺线段(可能只是线状要素的一部分)</param>
        ///  <param name="CToEdgeLt">小比例尺线段(可能只是线状要素的一部分)</param>
        /// <param name="frlastcpllt">大比例尺终点线段(只有一个点)</param>
        /// <param name="tolastcpllt">小比例尺终点线段(只有一个点)</param>
        /// <param name="intMaxBackK">回溯系数</param>
        /// <returns>T矩阵</returns>
        public CTable[,] CreatT(CPolyline frcpl, CPolyline tocpl, List <CPolyline> CFrBezierEdgeLt, List <CPolyline> CToBezierEdgeLt,
                                ref List <CPolyline> frlastcpllt, ref List <CPolyline> tolastcpllt, int intMaxBackK)
        {
            ////注意:T矩阵中的序号跟原文算法中的序号是统一的,但线数组中的序号则应减1
            //CTable[,] T = new CTable[CFrBezierEdgeLt.Count + 1, CToBezierEdgeLt.Count + 1];  //线段数量为顶点数量减1

            ////数组的第一行及第一列初始化
            //T[0, 0] = new CTable();
            //T[0, 0].dblEvaluation = 0;

            //CPolyline frfirstcpl = new CPolyline(0, CFrBezierEdgeLt[0].CptLt [0]);  //以线状要素的第一个点作为线段
            //for (int j = 1; j <= CToBezierEdgeLt.Count; j++)
            //{
            //    T[0, j] = new CTable();
            //    T[0, j].frpart = "first";
            //    T[0, j].frfrId = 1;
            //    T[0, j].topart = "segment";
            //    T[0, j].tofrId = j;
            //    CPolyline tocplj = tocpl.GetSubPolyline(CToBezierEdgeLt[j - 1].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[CToBezierEdgeLt[j - 1].CptLt.Count - 1]);
            //    T[0, j].dblEvaluation = T[0, j - 1].dblEvaluation + CalDistance(frfirstcpl, tocplj, frcpl, tocpl);
            //}

            //CPolyline tofirstcpl = new CPolyline(0, CToBezierEdgeLt[0].CptLt[0]);  //以线状要素的第一个点作为线段
            //for (int i = 1; i <= CFrBezierEdgeLt.Count; i++)
            //{
            //    T[i, 0] = new CTable();
            //    T[i, 0].frpart = "segment";
            //    T[i, 0].frfrId = i;
            //    T[i, 0].topart = "first";
            //    T[i, 0].tofrId = 1;
            //    CPolyline tocpli = frcpl.GetSubPolyline(CFrBezierEdgeLt[i - 1].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[CFrBezierEdgeLt[i - 1].CptLt.Count - 1]);
            //    T[i, 0].dblEvaluation = T[i - 1, 0].dblEvaluation + CalDistance(CFrBezierEdgeLt[i - 1], tofirstcpl, frcpl, tocpl);
            //}

            ////循环填满二维数组T中的各个值
            //for (int i = 0; i < CFrBezierEdgeLt.Count; i++)//大比例尺线段终点数据准备
            //{
            //    List<CPoint> frlastptlt = new List<CPoint>();
            //    frlastptlt.Add(CFrBezierEdgeLt[i].CptLt[1]);
            //    frlastcpllt.Add(new CPolyline(0, frlastptlt));
            //}

            //for (int i = 0; i < CToBezierEdgeLt.Count; i++)//小比例尺线段终点数据准备
            //{
            //    List<CPoint> frlastptlt = new List<CPoint>();
            //    frlastptlt.Add(CToBezierEdgeLt[i].CptLt[1]);
            //    tolastcpllt.Add(new CPolyline(0, frlastptlt));
            //}

            ////注意:T中的序号1指定第一个元素,而各LT中(如CFrBezierEdgeLt,tolastcpllt)的序号1则指定第二个元素
            //for (int i = 1; i <= CFrBezierEdgeLt.Count; i++)               //计算各空格值
            //{
            //    for (int j = 1; j <= CToBezierEdgeLt.Count; j++)
            //    {
            //        SortedDictionary<double, CTable> dblCTableSlt = new SortedDictionary<double, CTable>(new CCmpDbl());
            //        CPolyline subfrcpl1 = frcpl.GetSubPolyline(CFrBezierEdgeLt[i - 1].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[CFrBezierEdgeLt[i - 1].CptLt.Count - 1]);
            //        CPolyline subtocpl1 = tocpl.GetSubPolyline(CToBezierEdgeLt[j - 1].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[CToBezierEdgeLt[j - 1].CptLt.Count - 1]);

            //        //计算table1
            //        CTable table1 = new CTable();
            //        table1.frpart = "segment";
            //        table1.frfrId = i;
            //        table1.topart = "last";
            //        table1.tofrId = j;
            //        table1.dblEvaluation = T[i - 1, j].dblEvaluation + CalDistance(subfrcpl1, tolastcpllt[j - 1], frcpl, tocpl);
            //        dblCTableSlt.Add(table1.dblEvaluation, table1);

            //        //计算table2
            //        CTable table2 = new CTable();
            //        table2.frpart = "last";
            //        table2.frfrId = i;
            //        table2.topart = "segment";
            //        table2.tofrId = j;
            //        table2.dblEvaluation = T[i, j - 1].dblEvaluation + CalDistance(frlastcpllt[i - 1], subtocpl1, frcpl, tocpl);
            //        dblCTableSlt.Add(table2.dblEvaluation, table2);

            //        //计算table3
            //        CTable table3 = new CTable();
            //        table3.frpart = "segment";
            //        table3.frfrId = i;
            //        table3.topart = "segment";
            //        table3.tofrId = j;
            //        table3.dblEvaluation = T[i - 1, j - 1].dblEvaluation + CalDistance(subfrcpl1, subtocpl1, frcpl, tocpl);
            //        dblCTableSlt.Add(table3.dblEvaluation, table3);

            //        //计算table4j
            //        for (int k = 2; k <= intMaxBackK; k++)
            //        {
            //            if (j - k + 1 > 0)  //程序刚开始执行时,之前已遍历过线段数较少,可能小于intMaxBackK
            //            {
            //                CTable table4j = new CTable();
            //                table4j.frpart = "segment";
            //                table4j.frfrId = i;
            //                table4j.topart = "multisegments";
            //                table4j.tofrId = j - k + 1;
            //                table4j.totoId = j;
            //                table4j.intBackK = k;
            //                CPolyline tocplj = tocpl.GetSubPolyline(CToBezierEdgeLt[j - k].CptLt[0], CToBezierEdgeLt[j - 1].CptLt[1]);
            //                table4j.dblEvaluation = T[i - 1, j - k].dblEvaluation + CalDistance(subfrcpl1, tocplj, frcpl, tocpl);
            //                dblCTableSlt.Add(table4j.dblEvaluation, table4j);
            //            }
            //        }

            //        //计算table5i
            //        for (int k = 2; k <= intMaxBackK; k++)
            //        {
            //            if (i - k + 1 > 0)  //程序刚开始执行时,之前已遍历过线段数较少,可能小于intMaxBackK
            //            {
            //                CTable table5i = new CTable();
            //                table5i.frpart = "multisegments";
            //                table5i.frfrId = i - k + 1;
            //                table5i.frtoId = i;
            //                table5i.topart = "segment";
            //                table5i.tofrId = j;
            //                table5i.intBackK = k;
            //                CPolyline frcpli = frcpl.GetSubPolyline(CFrBezierEdgeLt[i - k].CptLt[0], CFrBezierEdgeLt[i - 1].CptLt[1]);
            //                table5i.dblEvaluation = T[i - k, j - 1].dblEvaluation + CalDistance(frcpli, subtocpl1, frcpl, tocpl);
            //                dblCTableSlt.Add(table5i.dblEvaluation, table5i);
            //            }
            //        }


            //        T[i, j] = dblCTableSlt.ElementAt(0).Value;
            //    }
            //}

            //int intRowNum = T.GetUpperBound(0);
            //int intColNum = T.GetUpperBound(1);
            //double dblTranslation = T[intRowNum, intColNum].dblEvaluation;
            //return T;
            return(null);
        }
 public virtual void btn100_Click(object sender, EventArgs e)
 {
     _dblProp = 1;
     _RelativeInterpolationCpl = _StraightLine.DisplayInterpolation(_dblProp);
 }
        /// <summary>计算距离值(Translation指标值)</summary>
        /// <param name="frcpl">大比例尺线段,可以只有一个顶点</param>
        /// <param name="tocpl">小比例尺线段,可以只有一个顶点</param>
        /// <returns>距离值</returns>
        public double CalDistance(CPolyline subfrcpl, CPolyline subtocpl, CPolyline frcpl, CPolyline tocpl)
        {
            List <CPoint> cresultptlt    = _LinearInterpolationA.CLI(subfrcpl, subtocpl); //每次都相当于处理新的线段,因此使用CLI
            double        dblTranslation = _pTranslation.CalTranslation(cresultptlt);

            return(dblTranslation);


            //List<CPoint> cresultptlt = _LinearInterpolationA.CLI(subfrcpl, subtocpl);  //每次都相当于处理新的线段,因此使用CLI
            //double dblCost1 = _pTranslation.CalRatioTranslation(cresultptlt, frcpl, tocpl);
            //double dblCost2 = _pIntegral.CalRatioIntegral(cresultptlt, frcpl, tocpl);
            //double dblCost3 = _pLengthDiff.CalRatioLengthDiff(cresultptlt, frcpl, tocpl);
            //double dblSumCost = dblCost1 + dblCost2 + dblCost3;
            //return dblSumCost;
        }
 public virtual void btnInputedScale_Click(object sender, EventArgs e)
 {
     _dblProp = Convert.ToDouble(this.txtProportion.Text);
     _RelativeInterpolationCpl = _StraightLine.DisplayInterpolation(_dblProp);
 }
 private void btnInputedScale_Click(object sender, EventArgs e)
 {
     _dblProp = Convert.ToDouble(this.txtProportion.Text);
     _RelativeInterpolationCpl = CDrawInActiveView.DisplayInterpolation(_DataRecords, _dblProp);
 }
Example #26
0
        /// <summary>
        /// 获取线状要素
        /// </summary>
        /// <param name="pDataRecords">数据记录</param>
        /// <param name="dblProp">插值参数</param>
        /// <returns>在处理面状要素时,本程序将原面状要素的边界切开,按线状要素处理,处理完后再重新生成面状要素</returns>
        public CPolyline GetTargetcpl(double dblProp)
        {
            List <CCorrCpts> pCorrCptsLt = _DataRecords.ParameterResult.CCorrCptsLt;   //读取数据后,此处ResultPtLt中的对应点为一一对应
            double           dblTX       = _dblTX;

            int intPtNum = pCorrCptsLt.Count;

            //计算长度初始值(全部计算)
            double[] adblLength0 = new double[intPtNum - 1];
            double[] adblLength  = new double[intPtNum - 1];  //可以变化的值
            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);
                adblLength0[i] = (1 - dblProp) * dblfrsublength + dblProp * dbltosublength;
                adblLength[i]  = adblLength0[i];
            }

            //计算角度初始值(全部计算)
            double[] adblAngle0 = new double[intPtNum - 2];
            double[] adblAngle  = 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;
                adblAngle[i]  = adblAngle0[i];
            }

            //生成点数组(初始值),同时计算各线段方位角混合值
            //注意:默认固定第一条边
            List <CPoint> cptlt = new List <CPoint>();

            double[] adblAzimuth = new double[intPtNum - 1];
            //计算第一个点和第二个点
            double dblnewX0 = (1 - dblProp) * pCorrCptsLt[0].FrCpt.X + dblProp * pCorrCptsLt[0].ToCpt.X;
            double dblnewY0 = (1 - dblProp) * pCorrCptsLt[0].FrCpt.Y + dblProp * pCorrCptsLt[0].ToCpt.Y;
            CPoint newcpt0  = new CPoint(0, dblnewX0, dblnewY0);

            newcpt0.isCtrl = true;
            cptlt.Add(newcpt0);
            double dblnewX1 = (1 - dblProp) * pCorrCptsLt[1].FrCpt.X + dblProp * pCorrCptsLt[1].ToCpt.X;
            double dblnewY1 = (1 - dblProp) * pCorrCptsLt[1].FrCpt.Y + dblProp * pCorrCptsLt[1].ToCpt.Y;
            CPoint newcpt1  = new CPoint(1, dblnewX1, dblnewY1);

            newcpt1.isCtrl = true;
            cptlt.Add(newcpt1);
            adblAzimuth[0] = CGeoFunc.CalAxisAngle(newcpt0, newcpt1);
            ////后面的其它点(不固定最后两个点)
            ////pCorrCptsLt[intPtNum - 2].FrCpt.isCtrl = false;
            ////pCorrCptsLt[intPtNum - 1].FrCpt.isCtrl = false;
            //for (int i = 2; i < pCorrCptsLt.Count; i++)
            //{
            //    CPoint newcpt = new CPoint();
            //    if (pCorrCptsLt[i].FrCpt.isCtrl == false)
            //    {
            //        adblAzimuth[i - 1] = adblAzimuth[i - 2] + adblAngle0[i - 2] - Math.PI;
            //        double dblnewX = cptlt[i - 1].X + adblLength0[i - 1] * Math.Cos(adblAzimuth[i - 1]);
            //        double dblnewY = cptlt[i - 1].Y + adblLength0[i - 1] * Math.Sin(adblAzimuth[i - 1]);
            //        newcpt = new CPoint(i, dblnewX, dblnewY);
            //    }
            //    else
            //    {
            //        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;
            //        newcpt = new CPoint(i, dblnewX, dblnewY);
            //        newcpt.isCtrl = true;

            //        //计算角度:不能采用“CGeoFunc.CalAxisAngle”,因为此处的方位角不一定在0到2Pi之间,采用重新连接法
            //        double dblAngle = CGeoFunc.CalAngle_Counterclockwise(cptlt[cptlt.Count - 2], cptlt[cptlt.Count - 1], newcpt);  //计算实际夹角
            //        adblAzimuth[i - 1] = adblAzimuth[i - 2] + dblAngle - Math.PI;
            //    }
            //    cptlt.Add(newcpt);
            //}

            //后面的其它点(固定最后两个点)
            for (int i = 2; i < pCorrCptsLt.Count - 2; i++)
            {
                CPoint newcpt = new CPoint();
                if (pCorrCptsLt[i].FrCpt.isCtrl == false)
                {
                    adblAzimuth[i - 1] = adblAzimuth[i - 2] + adblAngle0[i - 2] - Math.PI;
                    double dblnewX = cptlt[i - 1].X + adblLength0[i - 1] * Math.Cos(adblAzimuth[i - 1]);
                    double dblnewY = cptlt[i - 1].Y + adblLength0[i - 1] * Math.Sin(adblAzimuth[i - 1]);
                    newcpt = new CPoint(i, dblnewX, dblnewY);
                }
                else
                {
                    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;
                    newcpt        = new CPoint(i, dblnewX, dblnewY);
                    newcpt.isCtrl = true;

                    //计算角度:不能采用“CGeoFunc.CalAxisAngle”,因为此处的方位角不一定在0到2Pi之间,采用重新连接法
                    double dblAngle = CGeoFunc.CalAngle_Counterclockwise(cptlt[cptlt.Count - 2], cptlt[cptlt.Count - 1], newcpt);  //计算实际夹角
                    adblAzimuth[i - 1] = adblAzimuth[i - 2] + dblAngle - Math.PI;
                }
                cptlt.Add(newcpt);
            }
            //计算最后两个点
            double dblnewXlast1 = (1 - dblProp) * pCorrCptsLt[pCorrCptsLt.Count - 2].FrCpt.X + dblProp * pCorrCptsLt[pCorrCptsLt.Count - 2].ToCpt.X;
            double dblnewYlast1 = (1 - dblProp) * pCorrCptsLt[pCorrCptsLt.Count - 2].FrCpt.Y + dblProp * pCorrCptsLt[pCorrCptsLt.Count - 2].ToCpt.Y;
            CPoint newcptlast1  = new CPoint(pCorrCptsLt.Count - 2, dblnewXlast1, dblnewYlast1);

            newcptlast1.isCtrl = true;
            cptlt.Add(newcptlast1);
            double dblAnglelast1 = CGeoFunc.CalAngle_Counterclockwise(cptlt[cptlt.Count - 3], cptlt[cptlt.Count - 2], cptlt[cptlt.Count - 1]);  //计算实际夹角

            adblAzimuth[pCorrCptsLt.Count - 3] = adblAzimuth[pCorrCptsLt.Count - 4] + dblAnglelast1 - Math.PI;

            double dblnewXlast0 = (1 - dblProp) * pCorrCptsLt[pCorrCptsLt.Count - 1].FrCpt.X + dblProp * pCorrCptsLt[pCorrCptsLt.Count - 1].ToCpt.X;
            double dblnewYlast0 = (1 - dblProp) * pCorrCptsLt[pCorrCptsLt.Count - 1].FrCpt.Y + dblProp * pCorrCptsLt[pCorrCptsLt.Count - 1].ToCpt.Y;
            CPoint newcptlast0  = new CPoint(pCorrCptsLt.Count - 1, dblnewXlast0, dblnewYlast0);

            newcptlast0.isCtrl = true;
            cptlt.Add(newcptlast0);
            double dblAnglelast0 = CGeoFunc.CalAngle_Counterclockwise(cptlt[cptlt.Count - 3], cptlt[cptlt.Count - 2], cptlt[cptlt.Count - 1]);  //计算实际夹角

            adblAzimuth[pCorrCptsLt.Count - 2] = adblAzimuth[pCorrCptsLt.Count - 3] + dblAnglelast0 - Math.PI;


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

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

            //注意:对于该循环,有一个默认条件,即FromCpl的第一个顶点只有一个对应点
            for (int i = 0; i < cptlt.Count; i++)
            {
                if (cptlt[i].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 = cptlt.Count - 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 = cptlt.Count - 2 - intKnownAngleLt.Count;

            //总未知量
            int intUnknownLengthAngle = intUnknownLength + intUnknownAngle;

            //定义权重矩阵
            VBMatrix P = new VBMatrix(intUnknownLengthAngle, intUnknownLengthAngle);

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

            //定义权重矩阵倒数
            VBMatrix QLL = new VBMatrix(intUnknownLengthAngle, intUnknownLengthAngle);

            for (int i = 0; i < intUnknownLength; i++)
            {
                QLL[i, i] = 1;
            }
            for (int i = 0; i < intUnknownAngle; i++)
            {
                QLL[intUnknownLength + i, intUnknownLength + i] = 1;
            }
            //for (int i = 0; i < intXYCst; i++)
            //{
            //    P[intUnknownLengthAngle + i, intUnknownLengthAngle + i] = 1;
            //}
            //for (int i = 0; i < intAngleCst; i++)
            //{
            //    P[intUnknownLengthAngle + intXYCst + i, intUnknownLengthAngle + intXYCst + i] =100000;
            //}

            //计算初始值矩阵X0
            VBMatrix X0 = new VBMatrix(2 * intPtNum, 1);

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

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

            //定义系数矩阵B(各方程对长度、角度的导数值)
            VBMatrix B = new VBMatrix(intUnknownLengthAngle, intUnknownLengthAngle);

            for (int i = 0; i < intUnknownLengthAngle; i++)
            {
                B[i, i] = -1;
            }

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

            double[] dblSubDis = new double[intPtNum - 1];
            do
            {
                VBMatrix w = new VBMatrix(intUnknownLengthAngle, 1);

                //计算系数矩阵A第0行到"intUnknownLength"行的各元素,即线段长度对各未知数求偏导的值
                //先计算各分母值(注意:分母实际上是求偏导后的一部分值,但却恰好等于两点之间距离,因此其计算公式与距离计算公式相同
                dblSubDis = new double[intPtNum - 1];
                for (int i = 0; i < intPtNum - 1; i++)
                {
                    dblSubDis[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++)
                {
                    double dblAngle = 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] + dblAngle - Math.PI;
                }

                //开始计算系数矩阵第"intUnknownXY"行到"intUnknownXY+intUnknownLength-1"行的各元素
                int intKnownCount2   = 0;
                int intUnKnownCount2 = 0;
                for (int j = 0; j < intUnknownLength; j++)
                {
                    int intSumCount = intKnownCount2 + intUnKnownCount2;
                    if (cptlt[intSumCount].isCtrl == false && cptlt[intSumCount + 1].isCtrl == false)
                    {
                        A[j, 2 * intUnKnownCount2 + 0] = -Math.Cos(adblAzimuth[intSumCount]);
                        A[j, 2 * intUnKnownCount2 + 1] = -Math.Sin(adblAzimuth[intSumCount]);
                        A[j, 2 * intUnKnownCount2 + 2] = -A[j, 2 * intUnKnownCount2 + 0];
                        A[j, 2 * intUnKnownCount2 + 3] = -A[j, 2 * intUnKnownCount2 + 1];

                        w[j, 0] = dblSubDis[intSumCount] - adblLength[intSumCount];   //图方便,顺便计算matl

                        intUnKnownCount2 += 1;
                    }
                    else if (cptlt[intSumCount].isCtrl == false && cptlt[intSumCount + 1].isCtrl == true)
                    {
                        A[j, 2 * intUnKnownCount2 + 0] = -Math.Cos(adblAzimuth[intSumCount]);
                        A[j, 2 * intUnKnownCount2 + 1] = -Math.Sin(adblAzimuth[intSumCount]);

                        w[j, 0] = dblSubDis[intSumCount] - adblLength[intSumCount];   //图方便,顺便计算matl

                        intUnKnownCount2 += 1;
                    }
                    else if (cptlt[intSumCount].isCtrl == true && cptlt[intSumCount + 1].isCtrl == false)
                    {
                        //注意这种情况,由于"pCorrCptsLt[intSumCount].FrCpt.isCtrl == true"不占位子(即不占列),因此列序号依然为" 2 * intUnKnownCount2 + 0"和" 2 * intUnKnownCount2 + 1",而不是+2,+3
                        A[j, 2 * intUnKnownCount2 + 0] = Math.Cos(adblAzimuth[intSumCount]);
                        A[j, 2 * intUnKnownCount2 + 1] = Math.Sin(adblAzimuth[intSumCount]);

                        w[j, 0] = dblSubDis[intSumCount] - adblLength[intSumCount];   //图方便,顺便计算matl

                        intKnownCount2 += 1;
                    }
                    else
                    {
                        intKnownCount2 += 1;
                        j -= 1;
                    }
                }

                //计算系数矩阵A第"intUnknownXY+intUnknownLength"行到"intUnknownXY+intUnknownLength+intUnknownAngle"行的各元素,即角度对各未知数求偏导的值
                int intKnownCount3   = 0;
                int intUnKnownCount3 = 0;
                for (int j = 0; j < intUnknownAngle; j++)
                {
                    //真是太幸运了,虽然求两向量逆时针夹角时需分多种情况讨论,但各情况的导数形式却是一致的,节省了不少编程精力啊,哈哈
                    int intSumCount = intKnownCount3 + intUnKnownCount3;

                    //常用数据准备
                    double dblA2 = dblSubDis[intSumCount] * dblSubDis[intSumCount];
                    double dblB2 = dblSubDis[intSumCount + 1] * dblSubDis[intSumCount + 1];

                    //开始计算系数值,由于将以下三个情况排列组合将有八种情况,因此按如下方式计算
                    if (cptlt[intUnKnownCount3 + intKnownCount3].isCtrl == true && cptlt[intUnKnownCount3 + intKnownCount3 + 1].isCtrl == true && cptlt[intUnKnownCount3 + intKnownCount3 + 2].isCtrl == true)
                    {
                        intKnownCount3 += 1;
                        j -= 1;
                    }
                    else
                    {
                        double dblNewAngle = CGeoFunc.CalAngle_Counterclockwise(Xmix[2 * intSumCount + 0, 0], Xmix[2 * intSumCount + 1, 0],
                                                                                Xmix[2 * intSumCount + 2, 0], Xmix[2 * intSumCount + 3, 0],
                                                                                Xmix[2 * intSumCount + 4, 0], Xmix[2 * intSumCount + 5, 0]);
                        w[intUnknownLength + j, 0] = dblNewAngle - adblAngle[intSumCount];   //图方便,顺便计算matl

                        int intPreTrueNum           = 0;
                        int intUnKnownCount3orginal = intUnKnownCount3;
                        int intKnownCount3orginal   = intKnownCount3;
                        if (cptlt[intUnKnownCount3orginal + intKnownCount3orginal + 0].isCtrl == false)
                        {
                            //X1,Y1的导数值(注意:该部分是减数,因此值为导数的负数)
                            A[intUnknownLength + j, 2 * intUnKnownCount3orginal + 0] = -(Xmix[2 * intSumCount + 3, 0] - Xmix[2 * intSumCount + 1, 0]) / dblA2;
                            A[intUnknownLength + j, 2 * intUnKnownCount3orginal + 1] = (Xmix[2 * intSumCount + 2, 0] - Xmix[2 * intSumCount + 0, 0]) / dblA2;

                            intUnKnownCount3 += 1;
                        }
                        else
                        {
                            intPreTrueNum  += 1;
                            intKnownCount3 += 1;
                        }

                        if (cptlt[intUnKnownCount3orginal + intKnownCount3orginal + 1].isCtrl == false)
                        {
                            //X2,Y2的导数值
                            //A[intUnknownLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 2] = -(Xmix[2 * intSumCount + 5, 0] - Xmix[2 * intSumCount + 3, 0]) / dblB2 - (Xmix[2 * intSumCount + 3, 0] - Xmix[2 * intSumCount + 1, 0]) / dblA2;
                            //A[intUnknownLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 3] = (Xmix[2 * intSumCount + 4, 0] - Xmix[2 * intSumCount + 2, 0]) / dblB2 + (Xmix[2 * intSumCount + 2, 0] - Xmix[2 * intSumCount + 0, 0]) / dblA2;

                            A[intUnknownLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 2] = (Xmix[2 * intSumCount + 5, 0] - Xmix[2 * intSumCount + 3, 0]) / dblB2 + (Xmix[2 * intSumCount + 3, 0] - Xmix[2 * intSumCount + 1, 0]) / dblA2;
                            A[intUnknownLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 3] = -(Xmix[2 * intSumCount + 4, 0] - Xmix[2 * intSumCount + 2, 0]) / dblB2 - (Xmix[2 * intSumCount + 2, 0] - Xmix[2 * intSumCount + 0, 0]) / dblA2;
                        }
                        else
                        {
                            intPreTrueNum += 1;
                        }
                        if (cptlt[intUnKnownCount3orginal + intKnownCount3orginal + 2].isCtrl == false)
                        {
                            //X3,Y3的导数值
                            A[intUnknownLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 4] = -(Xmix[2 * intSumCount + 5, 0] - Xmix[2 * intSumCount + 3, 0]) / dblB2;
                            A[intUnknownLength + j, 2 * (intUnKnownCount3orginal - intPreTrueNum) + 5] = (Xmix[2 * intSumCount + 4, 0] - Xmix[2 * intSumCount + 2, 0]) / dblB2;
                        }
                    }
                }

                //一个中间值
                VBMatrix InvBQLLBt = new VBMatrix(intUnknownLengthAngle, intUnknownLengthAngle);
                for (int i = 0; i < intUnknownLengthAngle; i++)  //注意:此处之所以可以这样计算是因为B矩阵是元素为-1的对角矩阵,且QLL是对角矩阵
                {
                    InvBQLLBt[i, i] = 1 / (QLL[i, i] * QLL[i, i]);
                }

                //计算Q22
                VBMatrix TempQ22 = A.Trans() * InvBQLLBt * A;
                VBMatrix NegQ22  = TempQ22.Inv(TempQ22);
                VBMatrix Q22     = new VBMatrix(intUnknownXY, intUnknownXY);
                for (int i = 0; i < intUnknownXY; i++)
                {
                    for (int j = 0; j < intUnknownXY; j++)
                    {
                        Q22[i, j] = -NegQ22[i, j];
                    }
                }

                //计算Q12
                VBMatrix NegQ12 = InvBQLLBt * A * Q22;
                VBMatrix Q12    = new VBMatrix(intUnknownLengthAngle, intUnknownXY);
                for (int i = 0; i < intUnknownLengthAngle; i++)
                {
                    for (int j = 0; j < intUnknownXY; j++)
                    {
                        Q12[i, j] = -NegQ12[i, j];
                    }
                }

                //计算Q21
                VBMatrix Q21 = Q12.Trans();

                //计算Q11********************************************************************
                VBMatrix I = new VBMatrix(intUnknownLengthAngle, intUnknownLengthAngle);
                for (int i = 0; i < intUnknownLengthAngle; i++)
                {
                    I[i, i] = 1;
                }
                VBMatrix Q11 = InvBQLLBt * (I - A * Q21);

                //计算负v
                VBMatrix Negv = QLL * B.Trans() * Q11 * w;

                //计算负x
                VBMatrix Negx = Q21 * w;

                //对观测值进行改正
                int intSumCountL4 = 0;
                for (int i = 0; i < intUnknownLength; i++) //长度近似值部分
                {
                    if (cptlt[intSumCountL4].isCtrl == false || cptlt[intSumCountL4 + 1].isCtrl == false)
                    {
                        adblLength[intSumCountL4] = adblLength[intSumCountL4] - Negv[i, 0];
                    }
                    else
                    {
                        i -= 1;
                    }
                    intSumCountL4 += 1;
                }
                int intSumCountA4 = 0;
                for (int i = intUnknownLength; i < intUnknownLengthAngle; i++) //角度近似值部分
                {
                    if (cptlt[intSumCountA4].isCtrl == false || cptlt[intSumCountA4 + 1].isCtrl == false || cptlt[intSumCountA4 + 2].isCtrl == false)
                    {
                        adblAngle[intSumCountA4] = adblAngle[intSumCountA4] - Negv[i, 0];
                    }
                    else
                    {
                        i -= 1;
                    }
                    intSumCountA4 += 1;
                }

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

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

                intIterativeCount += 1;


                if (intIterativeCount >= 1000)
                {
                    break;
                }


                //这里只是随便取两个中间值以观测是否收敛

                dblJudge1 = Math.Abs(Negx[intJudgeIndex, 0]);
                dblJudge2 = Math.Abs(Negx[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];
                CTargetPtLt.Add(cpt);
            }
            CPolyline cpl = new CPolyline(0, CTargetPtLt);

            return(cpl);
        }