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()); }
/// <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); }
/// <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); }
/// <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); }