private CEnumIntersectionType DetectIntersectionParralelIncreaseCEdge2Righter(CEdge cedge1, CEdge cedge2, out CPoint IntersectCpt, out CEdge overlapcedge) { IntersectCpt = null; overlapcedge = null; if (CCmpMethods.CmpCptXY(cedge1.ToCpt, cedge2.FrCpt) == -1) //we compare both x and y so that we can handle two edges haveing no slope { return(CEnumIntersectionType.NoNo); } else if (CCmpMethods.CmpCptXY(cedge1.ToCpt, cedge2.FrCpt) == 0) //we compare both x and y so that we can handle two edges haveing no slope { IntersectCpt = cedge1.ToCpt; return(CEnumIntersectionType.ToFr); } else // if (CCmpMethods.CmpXY(cedge1.ToCpt, cedge2.FrCpt) == 1) //we compare both x and y so that we can handle two edges haveing no slope { CPoint frcpt = null; if (CCmpMethods.CmpCptXY(cedge1.FrCpt, cedge2.FrCpt) == 1) //we compare both x and y so that we can handle two edges haveing no slope { frcpt = cedge1.FrCpt; } else { frcpt = cedge2.FrCpt; } //overlapcedge = new CEdge(frcpt, cedge1.ToCpt); //to save memory, we don't record the overlapcedge IntersectCpt = cedge1.ToCpt; return(CEnumIntersectionType.Overlap); } }
/// <summary> /// The concept of touch is simpler than the type of intersection /// </summary> /// <returns></returns> /// <remarks>It turns out that we do not really need this function</remarks> public bool IsTouch() { CEdge cedge1 = _CEdge1; CEdge cedge2 = _CEdge2; cedge1.JudgeAndSetSlope(); cedge2.JudgeAndSetSlope(); CPoint IntersectCpt = null; //CEdge overlapcedge = null; //CEnumIntersectionType penumIntersectionType = CEnumIntersectionType.NoNo; if (cedge1.blnHasSlope == true && cedge2.blnHasSlope == true) //this is the normal case { //if (CCmpMethods.Cmp(cedge1.dblSlope, cedge2.dblSlope)==0) //parallel if (CCmpMethods.CmpDbl_ConstVerySmall(cedge1.dblSlope, cedge2.dblSlope) == 0) //parallel { if (CCmpMethods.CmpDbl_CoordVerySmall(cedge1.dblYIntercept, cedge2.dblYIntercept) == 0) { //parallel and with the same YIntercept return(IsTouchParralel(cedge1, cedge2, out IntersectCpt)); } else //parallel but not with the same YIntercept { return(false); } } else //not parallel { return(IsTouchNormal(cedge1, cedge2, out IntersectCpt)); } } else if (cedge1.blnHasSlope == true && cedge2.blnHasSlope == false) { return(IsTouchOneNoSlope(cedge1, cedge2, out IntersectCpt)); } else if (cedge1.blnHasSlope == false && cedge2.blnHasSlope == true) { return(IsTouchOneNoSlope(cedge2, cedge1, out IntersectCpt)); } else if (cedge1.blnHasSlope == false && cedge2.blnHasSlope == false) { //parallel and with the same X Coordinate if (CCmpMethods.CmpDbl_CoordVerySmall(cedge1.FrCpt.X, cedge2.FrCpt.X) == 0) { return(IsTouchParralel(cedge1, cedge2, out IntersectCpt)); } else //parallel but not with the same X Coordinate { return(false); } } //_enumIntersectionType = penumIntersectionType; _IntersectCpt = IntersectCpt; //_OverlapCEdge = overlapcedge; throw new ArgumentException("unexpected case!"); }
private static double MakeAngleCorrect(double dblAngle) { if (CCmpMethods.CmpDbl_ConstVerySmall(dblAngle, CConstants.dblTwoPI) == 0) { dblAngle = 0; } return(dblAngle); }
//public void SetSlope(ref List <CEdge > CEdgeLt) //{ // CGeoFunc.SetSlope(ref CEdgeLt); //} /// <summary>Detect the intesection between two edges</summary> /// <returns >the intersection point</returns> /// <remarks>the edges have to be set slope before using this function /// If the two edges overlap, then the IntersectCpt is the point with larger XY coordinate of the two ends of the overlap line segment /// </remarks> public void DetectIntersection() { CEdge cedge1 = _CEdge1; CEdge cedge2 = _CEdge2; cedge1.JudgeAndSetSlope(); cedge2.JudgeAndSetSlope(); CPoint IntersectCpt = null; CEdge overlapcedge = null; CEnumIntersectionType penumIntersectionType = CEnumIntersectionType.NoNo; if (cedge1.blnHasSlope == true && cedge2.blnHasSlope == true) //this is the normal case { //if (CCmpMethods.Cmp(cedge1.dblSlope, cedge2.dblSlope)==0) //parallel if (CCmpMethods.CmpDbl_ConstVerySmall(cedge1.dblSlope, cedge2.dblSlope) == 0) //parallel { if (CCmpMethods.CmpDbl_CoordVerySmall(cedge1.dblYIntercept, cedge2.dblYIntercept) == 0) //parallel and with the same YIntercept { penumIntersectionType = DetectIntersectionParralel(cedge1, cedge2, out IntersectCpt, out overlapcedge); } else //parallel but not with the same YIntercept { penumIntersectionType = CEnumIntersectionType.NoNo; } } else //not parallel { penumIntersectionType = DetectIntersectionNormal(cedge1, cedge2, out IntersectCpt); } } else if (cedge1.blnHasSlope == true && cedge2.blnHasSlope == false) { penumIntersectionType = DetectIntersectionOneNoSlope(cedge1, cedge2, out IntersectCpt); } else if (cedge1.blnHasSlope == false && cedge2.blnHasSlope == true) { penumIntersectionType = DetectIntersectionOneNoSlope(cedge2, cedge1, out IntersectCpt); penumIntersectionType = ReverseIntersectionType(penumIntersectionType); } else if (cedge1.blnHasSlope == false && cedge2.blnHasSlope == false) { if (CCmpMethods.CmpDbl_CoordVerySmall(cedge1.FrCpt.X, cedge2.FrCpt.X) == 0) //parallel and with the same X Coordinate { penumIntersectionType = DetectIntersectionParralel(cedge1, cedge2, out IntersectCpt, out overlapcedge); } else //parallel but not with the same X Coordinate { penumIntersectionType = CEnumIntersectionType.NoNo; } } _enumIntersectionType = penumIntersectionType; _IntersectCpt = IntersectCpt; _OverlapCEdge = overlapcedge; }
private static bool IsOnCEdge(CPoint cpt, CEdge cedge) { if (CCmpMethods.IsInbetween(cpt.X, cedge.FrCpt.X, cedge.ToCpt.X) == false || CCmpMethods.IsInbetween(cpt.Y, cedge.FrCpt.Y, cedge.ToCpt.Y) == false) { return(false); } else { return(true); } }
public void UnionCpl(CPolyline other, ref bool isUnioned) { isUnioned = true; var fcptlt = this.CptLt; var ocptlt = other.CptLt; var newcptlt = new List <CPoint>(); if (CCmpMethods.CmpCptYX(fcptlt.Last(), ocptlt.First()) == 0) { newcptlt.AddRange(fcptlt); newcptlt.RemoveLastT(); newcptlt.AddRange(ocptlt); } else if (CCmpMethods.CmpCptYX(fcptlt.Last(), ocptlt.Last()) == 0) { newcptlt.AddRange(fcptlt); newcptlt.RemoveLastT(); var copiedreversedcptlt = CHelpFunc.CopyCptLt(ocptlt); copiedreversedcptlt.Reverse(); newcptlt.AddRange(copiedreversedcptlt); } else if (CCmpMethods.CmpCptYX(fcptlt.First(), ocptlt.First()) == 0) { var copiedreversedcptlt = CHelpFunc.CopyCptLt(ocptlt); copiedreversedcptlt.Reverse(); newcptlt.AddRange(copiedreversedcptlt); newcptlt.RemoveLastT(); newcptlt.AddRange(fcptlt); } else if (CCmpMethods.CmpCptYX(fcptlt.First(), ocptlt.Last()) == 0) { //CPolyline cplCopyOther = other.CopyCpl(); newcptlt.AddRange(ocptlt); newcptlt.RemoveLastT(); newcptlt.AddRange(fcptlt); } else { isUnioned = false; return; } for (int i = 0; i < newcptlt.Count; i++) { newcptlt[i].ID = i; } FormPolyBase(newcptlt); }
private double CaInterLSubIntegral(CPoint frfrcpt, CPoint frtocpt, CPoint tofrcpt, CPoint totocpt, CPoint StandardVectorCpt, double dbInterLSmallDis, double dblVerySamll) { CPoint newfrfrcpt = new CPoint(0, frfrcpt.X + StandardVectorCpt.X, frfrcpt.Y + StandardVectorCpt.Y); CPoint newfrtocpt = new CPoint(0, frtocpt.X + StandardVectorCpt.X, frtocpt.Y + StandardVectorCpt.Y); CEdge frcedge = new CEdge(newfrfrcpt, newfrtocpt); CEdge tocedge = new CEdge(tofrcpt, totocpt); frcedge.SetLength(); tocedge.SetLength(); if (CCmpMethods.CmpCEdgeCoord(frcedge, tocedge, true) == 0 || (frcedge.dblLength == 0 && tocedge.dblLength == 0)) //为了应付刚开始时有重合的对应点 { return(0); } double dblLength = frcedge.dblLength; if (frcedge.dblLength < tocedge.dblLength) { dblLength = tocedge.dblLength; } int intSegmentNum = Convert.ToInt32(dblLength / dbInterLSmallDis) + 1; double frlength = frcedge.dblLength / intSegmentNum; double tolength = tocedge.dblLength / intSegmentNum; //梯形面积(因为所有的上底和下底都相同,因此可以先将各个梯形的高相加,再在循环外乘以高、除以2) double dbledgelength = 0; double dblRatio = 1 / Convert.ToDouble(intSegmentNum); double dblCurrentRatio = 0; for (int k = 0; k < intSegmentNum; k++) { double dblfrx = (1 - dblCurrentRatio) * newfrfrcpt.X + dblCurrentRatio * newfrtocpt.X; double dblfry = (1 - dblCurrentRatio) * newfrfrcpt.Y + dblCurrentRatio * newfrtocpt.Y; double dbltox = (1 - dblCurrentRatio) * tofrcpt.X + dblCurrentRatio * totocpt.X; double dbltoy = (1 - dblCurrentRatio) * tofrcpt.Y + dblCurrentRatio * totocpt.Y; dbledgelength += CGeoFunc.CalDis(dblfrx, dblfry, dbltox, dbltoy); dblCurrentRatio += dblRatio; } double dbInterLSubIntegral = dbledgelength * (frlength + tolength) / 2; return(dbInterLSubIntegral); }
private CEnumIntersectionType DetectIntersectionParralelIncrease(CEdge cedge1, CEdge cedge2, out CPoint IntersectCpt, out CEdge overlapcedge) { if (CCmpMethods.CmpCptXY(cedge1.ToCpt, cedge2.ToCpt) <= 0) //we compare both x and y so that we can handle two edges which have no slope { return(DetectIntersectionParralelIncreaseCEdge2Righter(cedge1, cedge2, out IntersectCpt, out overlapcedge)); } else { CEnumIntersectionType enumIntersectionType = DetectIntersectionParralelIncreaseCEdge2Righter(cedge2, cedge1, out IntersectCpt, out overlapcedge); return(ReverseIntersectionType(enumIntersectionType)); } }
/// <summary> /// /// </summary> /// <param name="cedgeComponent"></param> /// <param name="blnNext"></param> /// <returns></returns> private static CEdge TraverseToGetCorrectCEdgeComponent(CEdge cedgeComponent, CPoint cpt) { var currentcedge = cedgeComponent; do { if (CCmpMethods.CmpCptYX(currentcedge.FrCpt, cpt) == 0) { return(currentcedge); } currentcedge = currentcedge.cedgeNext; } while (currentcedge.GID != cedgeComponent.GID); throw new ArgumentException("we cannot find an appropriate edge!"); }
private CEnumIntersectionType DetectIntersectionParralel(CEdge cedge1, CEdge cedge2, out CPoint IntersectCpt, out CEdge overlapcedge) { CEdge auxCEdge1 = cedge1; bool blnReversed1 = false; if (CCmpMethods.CmpCptXY(cedge1.FrCpt, cedge1.ToCpt) == 1) { auxCEdge1 = new CEdge(cedge1.ToCpt, cedge1.FrCpt); blnReversed1 = true; } CEdge auxCEdge2 = cedge2; bool blnReversed2 = false; if (CCmpMethods.CmpCptXY(cedge2.FrCpt, cedge2.ToCpt) == 1) { auxCEdge2 = new CEdge(cedge2.ToCpt, cedge2.FrCpt); blnReversed2 = true; } CEnumIntersectionType penumIntersectionType = DetectIntersectionParralelIncrease(auxCEdge1, auxCEdge2, out IntersectCpt, out overlapcedge); if (penumIntersectionType == CEnumIntersectionType.FrTo || penumIntersectionType == CEnumIntersectionType.ToFr) //besides, penumIntersectionType coud be CEnumIntersectionType.NoNo or CEnumIntersectionType.Overlap { string substr1 = penumIntersectionType.ToString().Substring(0, 2); string substr2 = penumIntersectionType.ToString().Substring(2, 2); if (blnReversed1 == true) { substr1 = ReverseEnd(substr1); } if (blnReversed2 == true) { substr2 = ReverseEnd(substr2); } string strIntersectionType = substr1 + substr2; return((CEnumIntersectionType)Enum.Parse(typeof(CEnumIntersectionType), strIntersectionType)); } return(penumIntersectionType); }
public bool SetSlope() { this.dblIncrX = _ToCpt.X - _FrCpt.X; this.dblIncrY = _ToCpt.Y - _FrCpt.Y; //for we want to check topological relationships between edges, we use dblVerySmallCoordFixed instead of dblVerySmall, //where dblVerySmall will be changed during checking topological relationships //if (CCmpMethods.CmpDblRange(dblXDiff, 0, CConstants.dblVerySmallCoordFixed) == 0) //if (dblXDiff == 0) //this case would result we cannot identify a verticle line if (CCmpMethods.CmpDbl_CoordVerySmall(this.dblIncrX, 0) == 0) { _blnHasSlope = false; } else { _blnHasSlope = true; _dblSlope = this.dblIncrY / this.dblIncrX; _dblYIntercept = _FrCpt.Y - _dblSlope * _FrCpt.X; } return(_blnHasSlope); }
private static IEnumerable <CEdge> GenerateNewCEdgeEb(CEdge TargetCEdge, List <CptEdgeDis> CptEdgeDisLt) { var cpteb = CGeoFunc.RemoveClosePointsForCptEb(GetOrderedCptEb(TargetCEdge, CptEdgeDisLt)); var cpter = cpteb.GetEnumerator(); cpter.MoveNext(); var precpt = cpter.Current; while (cpter.MoveNext()) { if (CCmpMethods.CmpCptXY(precpt, cpter.Current) == 0) { throw new ArgumentException("small edge!"); } CEdge newcedge = new CEdge(precpt, cpter.Current); newcedge.BelongedCpg = TargetCEdge.BelongedCpg; yield return(newcedge); precpt = cpter.Current; } }
public int CompareTo(CCorrCpgSS other) { return(CCmpMethods.CmpColConsideringCount(FrCpgSS, ToCpgSS, cpg => cpg.GID)); }
public int CompareTo(CValPair <T1, T2> other) { return(CCmpMethods.CmpDual(this, other, valpair => valpair.val1, valpair => valpair.val2, this.cmp1, this.cmp2)); }
private CPolygon MergeGroupedCpgsAndBridges(List <CptEdgeDis> BridgeCptEdgeDisLt) { //we use HashSet so that each cpg will be added once var cpghs = new HashSet <CPolygon>(); foreach (var CptEdgeDis in BridgeCptEdgeDisLt) { cpghs.Add(CptEdgeDis.CpgPairIncr.val1); cpghs.Add(CptEdgeDis.CpgPairIncr.val2); } var cpglt = cpghs.ToList(); cpglt.ForEach(cpg => cpg.isTraversed = false); //some buildings may share boundaries, so we may have same edge //we use HashSet, instead of List, because we may remove some same edges var CEdgeHS = new HashSet <CEdge>(new CCmpEqCEdgeCoord()); cpglt.ForEach(cpg => cpg.CEdgeLt.ForEach(cedge => CEdgeHS.Add(cedge))); CGeoFunc.CheckShortEdges(CEdgeHS); var BridgeCEdgeLt = new List <CEdge>(cpglt.Count); var AllCEdgeLt = new List <CEdge>(CEdgeHS.Count + cpglt.Count); //the count is roughtly var CEdgeCptEdgeDisLtDt = new Dictionary <CEdge, List <CptEdgeDis> >(); foreach (var cptEdgeDis in BridgeCptEdgeDisLt) { //if (CCmpMethods.CmpDbl_CoordVerySmall(cptEdgeDis.dblDis, 0) == 0), then the two buildings touch each other if (CCmpMethods.CmpDbl_CoordVerySmall(cptEdgeDis.dblDis, 0) != 0) { //add the bridge as an edge BridgeCEdgeLt.Add(cptEdgeDis.ConnectCEdge); } //if the smallest distance of two polygons happen to between a point and an edge //this edge can be the closest edge of the polygon to several polygons, //so we will split the edge into several edges //here we record all the cases if (cptEdgeDis.t != 0 && cptEdgeDis.t != 1) { if (CEdgeCptEdgeDisLtDt.ContainsKey(cptEdgeDis.ToCEdge) == false) { CEdgeCptEdgeDisLtDt[cptEdgeDis.ToCEdge] = new List <CptEdgeDis>(); } CEdgeCptEdgeDisLtDt[cptEdgeDis.ToCEdge].Add(cptEdgeDis); } } AllCEdgeLt.AddRange(BridgeCEdgeLt); //CSaveFeature.SaveCEdgeEb(clipperMethods.ScaleCEdgeEb(AllCEdgeLt, 1 / CConstants.dblFclipper), // "BridgeCEdgeLt" + CHelpFunc.GetTimeStampWithPrefix()); //CGeoFunc.CheckShortEdges(AllCEdgeLt); //We need to split the edge into several edges foreach (var CEdgeCptEdgeDisLt in CEdgeCptEdgeDisLtDt) { var TargetCEdge = CEdgeCptEdgeDisLt.Key; if (CEdgeHS.Remove(TargetCEdge) == false) { throw new ArgumentException("This case should not be possible!"); } AllCEdgeLt.AddRange(GenerateNewCEdgeEb(TargetCEdge, CEdgeCptEdgeDisLt.Value)); } //CGeoFunc.CheckShortEdges(AllCEdgeLt); //if (CGeoFunc.ExistDuplicate(AllCEdgeLt, new CCmpCEdgeCoordinates())) //{ // throw new ArgumentException("There are duplicated edges!"); //} AllCEdgeLt.AddRange(CEdgeHS); var holecpglt = new List <CPolygon>(); foreach (var cpg in cpglt) { if (cpg.HoleCpgLt != null) { holecpglt.AddRange(cpg.HoleCpgLt); } } //CSaveFeature.SaveCEdgeEb(clipperMethods.ScaleCEdgeEb(AllCEdgeLt, 1 / CConstants.dblFclipper), // "MergedToConstructDCEL", blnVisible: false); CDCEL pDCEL = new CGeometry.CDCEL(AllCEdgeLt); pDCEL.ConstructDCEL(); var mergedcpg = new CPolygon(cpglt[0].ID, pDCEL.FaceCpgLt[0].GetOnlyInnerCptLt(), holecpglt); mergedcpg.CEdgeLt = pDCEL.FaceCpgLt[0].GetOnlyInnerCEdgeLt(); mergedcpg.BridgeCptEdgeDisLt = BridgeCptEdgeDisLt; mergedcpg.SubCpgLt = cpglt; return(mergedcpg); }
/// <summary> /// Makes a planar checks for if the points is spatially equal to another point. /// </summary> /// <param name="other">Point to check against</param> /// <returns>True if X and Y values are the same</returns> public bool Equals2D(CPoint other) { return(CCmpMethods.ConvertCmpToBool(CCmpMethods.CmpCptYX(this, other))); }
/// <summary> /// Makes a planar checks for if the points is spatially equal to another point. /// </summary> /// <param name="other">Point to check against</param> /// <returns>True if X and Y values are the same</returns> public bool Equals2D(CPoint other, double dblVerySmall) { return(CCmpMethods.ConvertCmpToBool(CCmpMethods.CmpCptYX(this, other))); }
public int CompareTo(CPairInt other) { return(CCmpMethods.CmpDual(this, other, cpi => cpi.Int1, cpi => cpi.Int2)); }
///// <summary>whether a point is in cedge (we already know that the point is on the line that goes through the cedge)</summary> ///// <returns> -1, nonsense, ///// 1, this point is not on the Edge ///// 2, this point is the FrCpt ///// 3, this point is in the Edge ///// 4, this point is the ToCpt</returns> ///// <remarks></remarks> /// <summary> /// /// </summary> /// <param name="cpt"></param> /// <param name="cedge"></param> /// <returns> "No", "Fr", "In", "To"</returns> public static string InCEdge(CPoint cpt, CEdge cedge) { //we test both x and y. if we only test one coordinate, we may get wrong result. // for example, there is an intersection that is actually in an edge, and this edge is almost vertical. // if we only test the x coordinate, then we will get that the intersection is the end (on the boundary) of this edge // because we use dblVerysmall to judge //cedge.SetLength(); int intCompareX = CCmpMethods.CmpThreeCoord(cpt.X, cedge.FrCpt.X, cedge.ToCpt.X); int intCompareY = CCmpMethods.CmpThreeCoord(cpt.Y, cedge.FrCpt.Y, cedge.ToCpt.Y); //the result is a result of a 6*6 matrix string strInCEdge = ""; if (intCompareX == 1 || intCompareX == 5 || intCompareY == 1 || intCompareY == 5) //this point is not on the Edge { strInCEdge = "No"; } else if (intCompareX == 3 || intCompareY == 3) //this point is in the Edge { strInCEdge = "In"; } else // if (intCompareX, intCompareY = 0, 2, 4), //this point is one of the ends of the Edge { if (intCompareX == 0) { if (intCompareY == 0 || intCompareY == 2) { strInCEdge = "Fr"; } else //if (intCompareY==4) { strInCEdge = "To"; } } else if (intCompareX == 2) { if (intCompareY == 0 || intCompareY == 2) { strInCEdge = "Fr"; } else //if (intCompareY==4) //unfortunately, this can happen!!! { //MessageBox.Show("This cannot happen! InCEdge!"); // strInCEdge = "In"; } } else //if (intCompareX == 4) { if (intCompareY == 0 || intCompareY == 4) { strInCEdge = "To"; } else //if (intCompareY==2) { //MessageBox.Show("This cannot happen! InCEdge!"); strInCEdge = "In"; } } } return(strInCEdge); }
//public virtual void JudgeAndSetZToZero() //{ // _pPoint.Z = 0; // this.Z = 0; //} public int Compare(CPoint other) { return(CCmpMethods.CmpCptYX(this, other)); }
/// <summary> /// /// </summary> /// <param name="LSCrg"></param> /// <param name="SSCrg"></param> /// <param name="StrObjLtDt"></param> /// <param name="adblTD"></param> /// <param name="EstStepsCostVPDt">Results from A*</param> /// <param name="strAreaAggregation"></param> /// <returns></returns> public CRegion Greedy(CRegion LSCrg, CRegion SSCrg, CStrObjLtDt StrObjLtDt, double[,] adblTD, Dictionary <int, CValPair <int, double> > EstStepsCostVPDt, string strAreaAggregation) { long lngStartMemory = GC.GetTotalMemory(true); var pStopwatchOverHead = Stopwatch.StartNew(); var ExistingCorrCphsSD0 = LSCrg.SetInitialAdjacency(); //also count the number of edges AddLineToStrObjLtDt(StrObjLtDt, LSCrg); Console.WriteLine(); Console.WriteLine("Crg: ID " + LSCrg.ID + "; n " + LSCrg.GetCphCount() + "; m " + LSCrg.AdjCorrCphsSD.Count + " " + CConstants.strShapeConstraint + " " + strAreaAggregation); long lngTimeOverHead = pStopwatchOverHead.ElapsedMilliseconds; pStopwatchOverHead.Stop(); var pStopwatchLast = new Stopwatch(); long lngTime = 0; CRegion resultcrg = new CRegion(-2); try { pStopwatchLast.Restart(); var ExistingCorrCphsSD = new SortedDictionary <CCorrCphs, CCorrCphs> (ExistingCorrCphsSD0, ExistingCorrCphsSD0.Comparer); LSCrg.cenumColor = CEnumColor.white; resultcrg = Compute(LSCrg, SSCrg, SSCrg.GetSoloCphTypeIndex(), strAreaAggregation, ExistingCorrCphsSD, StrObjLtDt, adblTD); } catch (System.OutOfMemoryException ex) { Console.WriteLine(ex.Message); } lngTime = pStopwatchLast.ElapsedMilliseconds + lngTimeOverHead; Console.WriteLine("d: " + resultcrg.d + " Type: " + resultcrg.dblCostExactType + " Compactness: " + resultcrg.dblCostExactComp); EstStepsCostVPDt.TryGetValue(LSCrg.ID, out CValPair <int, double> outEstStepsCostVP); if (outEstStepsCostVP.val1 == 0 && CCmpMethods.CmpDbl_CoordVerySmall(outEstStepsCostVP.val2, resultcrg.d) == 0) { StrObjLtDt.SetLastObj("EstSteps/Gap%", 0); //optimal solutions } else { StrObjLtDt.SetLastObj("EstSteps/Gap%", 100); //not sure, at least feasible solutions } //we don't need to +1 because +1 is already included in _intStaticGID //int intExploredRegionAll = CRegion._intStaticGID - CRegion._intStartStaticGIDLast; StrObjLtDt.SetLastObj("#Edges", CRegion._intEdgeCount); StrObjLtDt.SetLastObj("Time_F(ms)", lngTime); StrObjLtDt.SetLastObj("Time_L(ms)", lngTime); StrObjLtDt.SetLastObj("Time(ms)", lngTime); StrObjLtDt.SetLastObj("Memory(MB)", CHelpFunc.GetConsumedMemoryInMB(false, lngStartMemory)); Console.WriteLine("We have visited " + CRegion._intNodeCount + " Nodes and " + CRegion._intEdgeCount + " Edges."); return(resultcrg); }
//private void SgCplTraverse(CTriangulation pFrCtgl, List <CEdge > SgCEdgeLt, ref int intIndex) private CPolyline GenerateCorrSgCpl(CCptbCtgl pCptbCtgl, CPolyline SgCpl, SortedDictionary <CPoint, CPoint> pInterLSCptSD) { CTriangulation pFrCtgl = pCptbCtgl.FrCtgl; CTriangulation pToCtgl = pCptbCtgl.ToCtgl; var AffineCptLt = new List <CPoint>(SgCpl.CptLt.Count); AffineCptLt.Add(CalFirstAffineCpt(pCptbCtgl, SgCpl.CptLt[0], pInterLSCptSD)); //the first vertex SgCpl.JudgeAndFormCEdgeLt(); //CareCEdge is an edge that current edge may cross with current triangle //CareCEdgeLt has three edges at most var CareCEdgeLt = FindCareCEdgeLtForFirstCEdge(pFrCtgl, SgCpl.CEdgeLt[0], pInterLSCptSD); if (SgCpl.CEdgeLt.Count == 1 && CCmpMethods.CmpCEdgeCoord(CareCEdgeLt[0], SgCpl.CEdgeLt[0]) == 0) { //this is a special case where a single polyline has only one edge (SgCEdge), //at the same time, this edge is used by the combined triangulation var newCEdge = pToCtgl.HalfEdgeLt[CareCEdgeLt[0].indexID]; AffineCptLt.Add(newCEdge.ToCpt); return(new CPolyline(SgCpl.ID, AffineCptLt)); } int intEdgeCount = 0; var CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount++]; do { bool isFoundExit = false; //whether this edge can go out current polygon (a triangle) foreach (var carecedge in CareCEdgeLt) { var pIntersection = CurrentCEdge.IntersectWith(carecedge); switch (pIntersection.enumIntersectionType) { case CEnumIntersectionType.NoNo: break; //this case is actually only for the fisrt vertex of a SgCpl, //because for other intersections which coincide a triangulation node, //we would not add the two neighbour edges in to CareCEdgeLt case CEnumIntersectionType.FrFr: CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge); isFoundExit = true; break; //this case is actually only for the fisrt vertex of a SgCpl, //because for other intersections which coincide a triangulation node, //we would not add the two neighbour edges in to CareCEdgeLt case CEnumIntersectionType.FrIn: //this can happen, when the first SgCpt is on an triangle edge of FrCtgl CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false); isFoundExit = true; break; //this case is actually only for the fisrt vertex of a SgCpl, //because for other intersections which coincide a triangulation node, //we would not add the two neighbour edges in to CareCEdgeLt case CEnumIntersectionType.FrTo: CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge); //this can happen isFoundExit = true; break; case CEnumIntersectionType.InFr: AffineCptLt.Add(pToCtgl.CptLt[carecedge.FrCpt.indexID]); CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge); isFoundExit = true; break; case CEnumIntersectionType.InIn: AffineCptLt.Add(ComputeAffineCptForInbetween(pToCtgl, pIntersection)); CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false); isFoundExit = true; break; case CEnumIntersectionType.InTo: AffineCptLt.Add(pToCtgl.CptLt[carecedge.ToCpt.indexID]); CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge); isFoundExit = true; break; case CEnumIntersectionType.ToFr: //come to the end of an edge AffineCptLt.Add(pToCtgl.CptLt[carecedge.FrCpt.indexID]); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge); } intEdgeCount++; isFoundExit = true; break; case CEnumIntersectionType.ToIn: //come to the end of an edge AffineCptLt.Add(ComputeAffineCptForInbetween(pToCtgl, pIntersection)); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false); } intEdgeCount++; isFoundExit = true; break; case CEnumIntersectionType.ToTo: //come to the end of an edge AffineCptLt.Add(pToCtgl.CptLt[carecedge.ToCpt.indexID]); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge); } intEdgeCount++; isFoundExit = true; break; //maybe we can just ignore overlap, because if there is overlap, then there is also other cases case CEnumIntersectionType.Overlap: MessageBox.Show("we didn't consider Overlap when GenerateCorrSgCpl in:" + this.ToString() + ".cs "); break; default: break; } if (isFoundExit == true) { break; } } if (isFoundExit == false) //come to the end of an edge { AffineCptLt.Add(CalAffineCpt(CurrentCEdge.ToCpt, CareCEdgeLt[0], pFrCtgl, pToCtgl)); if (intEdgeCount < SgCpl.CEdgeLt.Count) { CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount]; CareCEdgeLt = GetCareCEdgeLt(CareCEdgeLt[0], true); } intEdgeCount++; } } while (intEdgeCount <= SgCpl.CEdgeLt.Count); return(new CPolyline(SgCpl.ID, AffineCptLt)); }
private static double CalDeflectionSub(CCorrCpts LastCorrCpts, CCorrCpts CurrentCorrCpts, double dblfrlength, double dbltolength) { CPoint frfrcpt = LastCorrCpts.FrCpt; //vertex1 CPoint frtocpt = CurrentCorrCpts.FrCpt; //vertex2 CPoint tofrcpt = LastCorrCpts.ToCpt; //vertex3 CPoint totocpt = CurrentCorrCpts.ToCpt; //vertex4 //double dblfrfrX = LastCorrCpts.FrCpt.X + pStandardVectorCpt.X; //x1 //double dblfrfrY = LastCorrCpts.FrCpt.Y + pStandardVectorCpt.Y; //y1 //double dblfrtoX = CurrentCorrCpts.FrCpt.X + pStandardVectorCpt.X; //x2 //double dblfrtoY = CurrentCorrCpts.FrCpt.Y + pStandardVectorCpt.Y; //y2 double dblfftfx = frfrcpt.X - tofrcpt.X; //x1-x3 double dblfftfy = frfrcpt.Y - tofrcpt.Y; //y1-y3 double dblXPart = dblfftfx - frtocpt.X + totocpt.X; //x1-x2-x3+x4 double dblYPart = dblfftfy - frtocpt.Y + totocpt.Y; //y1-y2-y3+y4 //Integral of sqrt(ax^2+bx+c); X=ax^2+bx+c, delta=4ac-b^2; k=4a/delta double a = dblXPart * dblXPart + dblYPart * dblYPart; double b = -2 * (dblfftfx * dblXPart + dblfftfy * dblYPart); double c = dblfftfx * dblfftfx + dblfftfy * dblfftfy; double dblTwoA = a + a; double dblFourA = dblTwoA + dblTwoA; CQuadraticEquation pQuadraticEquation = new CQuadraticEquation(a, b, c); //since this is a function of distance, dblDelta <= 0 double dblIntegral = 0; //we have a>=0 if (CCmpMethods.CmpSquare(a, 0) == 0) //then b==0 { dblIntegral = Math.Sqrt(c); } else { //f(x)=ax^2+bx+c, f(0)=c, f(1)=a+b+c double X_0 = c; double X_1 = CMath.JudgeNegtiveReturn0(a + b + c, "X1"); double SqrtX_0 = Math.Sqrt(X_0); double SqrtX_1 = Math.Sqrt(X_1); double dblTwoAUplusB_0 = b; //U = 0 double dblTwoAUplusB_1 = dblTwoA + b; //U = 1 //double dblDelta = CMath double dblFirstPart = (dblTwoAUplusB_1 * SqrtX_1 - dblTwoAUplusB_0 * SqrtX_0) / dblFourA; //(2 * a * 1 + b) * SqrtX_1 / (4 * a) - (2 * a * 0 + b) * SqrtX_0 / (4 * a) double dblSecondPart = 0; //two line segments are parallel to each other is a special case of Delta=0, notice that the distance between the two parallel segments is changing if (CCmpMethods.CmpPower4(pQuadraticEquation.dblDelta, 0) != 0) { double dblSqrtA = Math.Sqrt(a); double dblTwoSqrtA = 2 * dblSqrtA; //double dblk = dblFourA / (-pQuadraticEquation.dblDelta); double dblfisrtpart = dblTwoSqrtA * SqrtX_1 + dblTwoAUplusB_1; //the part in ln when u=1 double dblsecondpart = dblTwoSqrtA * SqrtX_0 + dblTwoAUplusB_0; //the part in ln when u=0 double dblAbsPart = dblfisrtpart / dblsecondpart; //the ln part double dblLnPart = Math.Log(dblAbsPart); //Math.Log(2 * dblSqrtA * SqrtX_1 + 2 * a * 1 + b) - * Math.Log(2 * dblSqrtA * SqrtX_0 + 2 * a * 0 + b); dblSecondPart = -pQuadraticEquation.dblDelta * dblLnPart / dblFourA / dblTwoSqrtA; //dblSecondPart = dblSubSecondPart / (2 * dblk); if (double.IsNaN(dblSecondPart)) //sometimes, the ComparePower4 doesn't work well { dblSecondPart = 0; } } dblIntegral = dblFirstPart + dblSecondPart; } double dblResult = dblIntegral * (dblfrlength + dbltolength); return(dblResult); }