private Site GetRightRegion(HalfEdge halfEdge) { // if this halfedge has no edge, return the bottom site if (halfEdge.Edge == (Edge)null) { return this.bottomSite; } // if ELpm = 0, return the site 0 that this edge bisects, otherwise return site 1 Site answer = halfEdge.ELpm == LEdge ? halfEdge.Edge.Region[REdge] : halfEdge.Edge.Region[LEdge]; return answer; }
// create a new site where the HalfEdges intersect private Site Intersect(HalfEdge firstHalfEdge, HalfEdge secondHalfEdge) { Edge edge; HalfEdge halfEdge; bool isRightOfSite; // vertex Edge firstEdge = firstHalfEdge.Edge; Edge secondEdge = secondHalfEdge.Edge; if (firstEdge == null || secondEdge == null) { return null; } // if the two edges bisect the same parent, return null if (firstEdge.Region[1] == secondEdge.Region[1]) { return null; } double distance = (firstEdge.A * secondEdge.B) - (firstEdge.B * secondEdge.A); if (-1.0e-10 < distance && distance < 1.0e-10) { return null; } double intersectionPointX = ((firstEdge.C * secondEdge.B) - (secondEdge.C * firstEdge.B)) / distance; double intersectionPointY = ((secondEdge.C * firstEdge.A) - (firstEdge.C * secondEdge.A)) / distance; if ((firstEdge.Region[1].Coordinates.Y < secondEdge.Region[1].Coordinates.Y) || (firstEdge.Region[1].Coordinates.Y == secondEdge.Region[1].Coordinates.Y && firstEdge.Region[1].Coordinates.X < secondEdge.Region[1].Coordinates.X)) { halfEdge = firstHalfEdge; edge = firstEdge; } else { halfEdge = secondHalfEdge; edge = secondEdge; } isRightOfSite = intersectionPointX >= edge.Region[1].Coordinates.X; if ((isRightOfSite && halfEdge.ELpm == LEdge) || (!isRightOfSite && halfEdge.ELpm == REdge)) { return null; } // create a new site at the point of intersection - this is a new vector; event waiting to happen Site intersectionSite = new Site(); intersectionSite.Coordinates.X = intersectionPointX; intersectionSite.Coordinates.Y = intersectionPointY; return intersectionSite; }
private void DeleteHalfEdge(HalfEdge halfEdge) { halfEdge.LeftHalfEdge.RightHalfEdge = halfEdge.RightHalfEdge; halfEdge.RightHalfEdge.LeftHalfEdge = halfEdge.LeftHalfEdge; halfEdge.IsDeleted = true; }
// returns true if point is to right of halfedge private bool GetIsRightOf(HalfEdge halfEdge, Point point) { bool isRightOfHalfEdge; bool isAbove, isFast; double dXP, dYP, dXS, t1, t2, t3, yl; Edge edge = halfEdge.Edge; Site topSite = edge.Region[1]; if (point.X > topSite.Coordinates.X) { isRightOfHalfEdge = true; } else { isRightOfHalfEdge = false; } if (isRightOfHalfEdge && halfEdge.ELpm == LEdge) { return true; } if (!isRightOfHalfEdge && halfEdge.ELpm == REdge) { return false; } if (edge.A == 1.0) { dXP = point.X - topSite.Coordinates.X; dYP = point.Y - topSite.Coordinates.Y; isFast = false; if ((!isRightOfHalfEdge & (edge.B < 0.0)) | (isRightOfHalfEdge & (edge.B >= 0.0))) { isAbove = dYP >= edge.B * dXP; isFast = isAbove; } else { isAbove = point.X + (point.Y * edge.B) > edge.C; if (edge.B < 0.0) { isAbove = !isAbove; } if (!isAbove) { isFast = true; } } if (!isFast) { dXS = topSite.Coordinates.X - edge.Region[0].Coordinates.X; isAbove = edge.B * ((dXP * dXP) - (dYP * dYP)) < dXS * dYP * (1.0 + (2.0 * dXP / dXS) + (edge.B * edge.B)); if (edge.B < 0) { isAbove = !isAbove; } } } else { yl = edge.C - (edge.A * point.X); t1 = point.Y - yl; t2 = point.X - topSite.Coordinates.X; t3 = yl - topSite.Coordinates.Y; isAbove = (t1 * t1) > (t2 * t2) + (t3 * t3); } bool answer = halfEdge.ELpm == LEdge ? isAbove : !isAbove; return answer; }
private Site GetLeftRegion(HalfEdge halfEdge) { if (halfEdge.Edge == null) { return this.bottomSite; } Site leftRegion = halfEdge.ELpm == LEdge ? halfEdge.Edge.Region[LEdge] : halfEdge.Edge.Region[REdge]; return leftRegion; }
private void InsertHalfEdge(HalfEdge leftBoundary, HalfEdge newHalfEdge) { newHalfEdge.LeftHalfEdge = leftBoundary; newHalfEdge.RightHalfEdge = leftBoundary.RightHalfEdge; leftBoundary.RightHalfEdge.LeftHalfEdge = newHalfEdge; leftBoundary.RightHalfEdge = newHalfEdge; }
private HalfEdge RightHalfEdge(HalfEdge halfEdge) { return halfEdge.RightHalfEdge; }
private HalfEdge LeftHalfEdge(HalfEdge halfEdge) { return halfEdge.LeftHalfEdge; }
private bool InitEdgeList() { this.edgeListHashSize = 2 * this.sitesCountSqrt; this.edgeListHash = new HalfEdge[this.edgeListHashSize]; for (int i = 0; i < this.edgeListHashSize; i++) { this.edgeListHash[i] = null; } this.edgeListLeftEnd = this.CreateHalfEdge(null, 0); this.edgeListRightEnd = this.CreateHalfEdge(null, 0); this.edgeListLeftEnd.LeftHalfEdge = null; this.edgeListLeftEnd.RightHalfEdge = this.edgeListRightEnd; this.edgeListRightEnd.LeftHalfEdge = this.edgeListLeftEnd; this.edgeListRightEnd.RightHalfEdge = null; this.edgeListHash[0] = this.edgeListLeftEnd; this.edgeListHash[this.edgeListHashSize - 1] = this.edgeListRightEnd; return true; }
private HalfEdge CreateHalfEdge(Edge edge, int pm) { HalfEdge halfEdge = new HalfEdge(); halfEdge.Edge = edge; halfEdge.ELpm = pm; halfEdge.NextPriorityQueueMember = null; halfEdge.Vertex = null; return halfEdge; }
// remove the HalfEdge from the list of vertices private void DeleteHalfEdgeFromPriorityQueue(HalfEdge halfEdge) { if (halfEdge.Vertex != null) { HalfEdge lastHalfEdge = this.priorityQueueHash[this.GetPriorityQueueBucket(halfEdge)]; while (lastHalfEdge.NextPriorityQueueMember != halfEdge) { lastHalfEdge = lastHalfEdge.NextPriorityQueueMember; } lastHalfEdge.NextPriorityQueueMember = halfEdge.NextPriorityQueueMember; this.priorityQueueMembersCount--; halfEdge.Vertex = null; } }
// push the HalfEdge into the ordered linked list of vertices private void InsertHalfEdgeInPriorityQueue(HalfEdge halfEdge, Site site, double offset) { HalfEdge nextHalfEdge; halfEdge.Vertex = site; halfEdge.YStart = (double)(site.Coordinates.Y + offset); HalfEdge lastHalfEdge = this.priorityQueueHash[this.GetPriorityQueueBucket(halfEdge)]; while ((nextHalfEdge = lastHalfEdge.NextPriorityQueueMember) != null && (halfEdge.YStart > nextHalfEdge.YStart || (halfEdge.YStart == nextHalfEdge.YStart && site.Coordinates.X > nextHalfEdge.Vertex.Coordinates.X))) { lastHalfEdge = nextHalfEdge; } halfEdge.NextPriorityQueueMember = lastHalfEdge.NextPriorityQueueMember; lastHalfEdge.NextPriorityQueueMember = halfEdge; this.priorityQueueMembersCount++; }
private int GetPriorityQueueBucket(HalfEdge halfEdge) { int bucket = (int)((halfEdge.YStart - this.minY) / this.deltaY * this.priorityQueueHashSize); if (bucket < 0) { bucket = 0; } if (bucket >= this.priorityQueueHashSize) { bucket = this.priorityQueueHashSize - 1; } if (bucket < this.priorityQueueMinMember) { this.priorityQueueMinMember = bucket; } return bucket; }