/// <summary> /// /// </summary> /// <param name="pCptbCtgl"></param> /// <param name="SgCpt"></param> /// <returns></returns> /// <remarks >the first or last vertex of a SgCpl can be computed many times, but it doesn't matter</remarks> private CPoint CalFirstAffineCpt(CCptbCtgl pCptbCtgl, CPoint SgCpt, SortedDictionary <CPoint, CPoint> pInterLSCptSD) { CTriangulation pFrCtgl = pCptbCtgl.FrCtgl; CTriangulation pToCtgl = pCptbCtgl.ToCtgl; CPoint AffineCpt = null; CPoint outcpt; bool blnContainsKey = pInterLSCptSD.TryGetValue(SgCpt, out outcpt); if (blnContainsKey == true) { AffineCpt = pToCtgl.CptLt[outcpt.indexID]; } else { AffineCpt = CalFirstSingleAffineCpt(SgCpt, pFrCtgl, pToCtgl); } return(AffineCpt); }
private CPoint CalAffineCpt(CPoint SgCpt, CEdge CareCEdge, CTriangulation pFrCtgl, CTriangulation pToCtgl) { var CurrentCEdge = CareCEdge; var atrianglecpt = new CPoint[3]; for (int i = 0; i < 3; i++) { atrianglecpt[i] = CurrentCEdge.FrCpt; CurrentCEdge = CurrentCEdge.cedgeNext; } double dblLamda1, dblLamda2, dblLamda3; CGeoFunc.CalBarycentricCoordinates(SgCpt, atrianglecpt[0], atrianglecpt[1], atrianglecpt[2], out dblLamda1, out dblLamda2, out dblLamda3); var AffineCpt = CGeoFunc.CalCartesianCoordinates(pToCtgl.CptLt[atrianglecpt[0].indexID], pToCtgl.CptLt[atrianglecpt[1].indexID], pToCtgl.CptLt[atrianglecpt[2].indexID], dblLamda1, dblLamda2, dblLamda3, SgCpt.ID); return(AffineCpt); }
private List <CEdge> FindCareCEdgeLtForFirstCEdge(CTriangulation pFrCtgl, CEdge FirstSgCEdge, SortedDictionary <CPoint, CPoint> pInterLSCptSD) { var pFrCpt = FirstSgCEdge.FrCpt; var CareCEdgeLt = new List <CEdge>(); CPoint outcpt; bool blnContainsKey = pInterLSCptSD.TryGetValue(pFrCpt, out outcpt); if (blnContainsKey == true) { CareCEdgeLt = GetCareCEdgeLtCptCoincident(outcpt, FirstSgCEdge, true); } else { //we have already computed FirstSgCEdge.FrCpt.ClosestLeftCIntersection.CEdge2 //when we computed the affine point for the first point CareCEdgeLt = GetCareCEdgeLt(pFrCpt.ClosestLeftCIntersection.CEdge2, true); } return(CareCEdgeLt); }
private CPoint CalFirstSingleAffineCpt(CPoint SgCpt, CTriangulation pFrCtgl, CTriangulation pToCtgl) { var CurrentCEdge = pFrCtgl.DetectCloestLeftCorrectCEdge(SgCpt); return(CalAffineCpt(SgCpt, CurrentCEdge, pFrCtgl, pToCtgl)); }
private CPoint ComputeAffineCptForInbetween(CTriangulation pToCtgl, CIntersection pIntersection) { var dblProp = pIntersection.CEdge2.CalInbetweenCptProportion(pIntersection.IntersectCpt); return(pToCtgl.HalfEdgeLt[pIntersection.CEdge2.indexID].GetInbetweenCpt(dblProp)); }
//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)); }