private static bool BisectorSegment(Plan.Vertex vertex, Vector2 segmentA, Vector2 segmentB, out float offset) { IntersectionRaySegment2 intersection; if (Intersect.RaySegment(vertex.position, vertex.bisector, segmentA, segmentB, out intersection)) { if (intersection.type == IntersectionType.Point) { Vector2 segmentDirection = (segmentB - segmentA).normalized; float toIntersection = Vector2.Distance(vertex.position, intersection.pointA); float intersectionAngle = Vector2.Angle(vertex.bisector, segmentDirection); float intersectionSin = Mathf.Sin(intersectionAngle * Mathf.Deg2Rad); float bisectorSin = Geometry.GetAngleBisectorSin(vertex.angle); offset = toIntersection / (1 / intersectionSin + 1 / bisectorSin); return(true); } // BEGIN: Modified by Microsoft Corporation for generic logging purposes. API.MREAPI.Logger.LogError(string.Format("Invalid bisector intersection\ntype: {0}\npointA: {1} pointB: {2}\nray: {3} segmentA:{4} segmentB:{5}", intersection.type, intersection.pointA, intersection.pointB, vertex.bisector, segmentA, segmentB)); // END: Modified by Microsoft Corporation for generic logging purposes. offset = 0; return(false); } offset = 0; return(false); }
private void ProcessIntersectionEvent(Plan plan, IntersectionEvent intersectionEvent) { foreach (var chain in intersectionEvent.chains) { SimplifyChain(plan, chain); } intersectionEvent.chains.RemoveAll(c => c.Count == 0); if (intersectionEvent.chains.Count >= 2) { for (var i = 0; i < intersectionEvent.chains.Count; i++) { var chain = intersectionEvent.chains[i]; var previousChain = intersectionEvent.chains.GetLooped(i - 1); var vertex = chain[0]; plan.Remove(vertex); skeleton.AddVertex(vertex); var newVertex = new Plan.Vertex(intersectionEvent.position) { previousPolygonIndex = vertex.previousPolygonIndex, nextPolygonIndex = previousChain[0].nextPolygonIndex }; plan.Insert(newVertex, vertex.previous, previousChain[0].next); CalculateBisector(newVertex); } } }
private static bool BisectorBisector(Plan.Vertex vertexA, Plan.Vertex vertexB, out float offset) { IntersectionRayRay2 intersection; if (Intersect.RayRay(vertexA.position, vertexA.bisector, vertexB.position, vertexB.bisector, out intersection)) { if (intersection.type == IntersectionType.Point) { float offsetA = GetBisectorBisectorOffset(vertexA, intersection.pointA); float offsetB = GetBisectorBisectorOffset(vertexB, intersection.pointA); offset = Mathf.Min(offsetA, offsetB); return(true); } if (intersection.type == IntersectionType.Segment) { float toIntersection = Vector2.Distance(vertexA.position, vertexB.position); float offsetA = GetBisectorBisectorOffset(vertexA, toIntersection) / 2; float offsetB = GetBisectorBisectorOffset(vertexB, toIntersection) / 2; offset = Mathf.Min(offsetA, offsetB); return(true); } // BEGIN: Modified by Microsoft Corporation for generic logging purposes. API.MREAPI.Logger.LogError(string.Format("Invalid bisector intersection\ntype: {0}\npointA: {1} pointB: {2}\nbisectorA: {3} bisectorB:{4}", intersection.type, intersection.pointA, intersection.pointB, vertexA.bisector, vertexB.bisector)); // END: Modified by Microsoft Corporation for generic logging purposes. offset = 0; return(false); } offset = 0; return(false); }
private void SimplifyChain(Plan plan, List <Plan.Vertex> chain) { if (chain.Count == 1) { return; } var first = chain[0]; var previous = first.previous; var last = chain[chain.Count - 1]; var next = last.next; foreach (var vertex in chain) { plan.Remove(vertex); skeleton.AddVertex(vertex); } chain.Clear(); if (next != first) { var newVertex = new Plan.Vertex(first.position) { previousPolygonIndex = first.previousPolygonIndex, nextPolygonIndex = last.nextPolygonIndex, }; plan.Insert(newVertex, previous, next); chain.Add(newVertex); CalculateBisector(newVertex); } }
private static void CalculateBisector(Plan.Vertex vertex) { Plan.Vertex previous = vertex.previous; Plan.Vertex next = vertex.next; float angle; Vector2 direction = Geometry.GetAngleBisector(previous.position, vertex.position, next.position, out angle); vertex.angle = angle; vertex.bisector = direction; }
public void AddVertex(Plan.Vertex vertex) { if (vertex.previousPolygonIndex == vertex.nextPolygonIndex) { AddVertex(vertex.previousPolygonIndex, vertex.position); } else { AddVertex(vertex.previousPolygonIndex, vertex.position); AddVertex(vertex.nextPolygonIndex, vertex.position); } }
private Plan.Vertex CreateSplitVertex(Plan plan, Vector2 position, Plan.Vertex segmentA, Plan.Vertex segmentB) { var newVertex = new Plan.Vertex(position) { previousPolygonIndex = segmentA.nextPolygonIndex, nextPolygonIndex = segmentB.previousPolygonIndex }; plan.Insert(newVertex, segmentA, segmentB); CalculateBisector(newVertex); return(newVertex); }
private IntersectionEvent FindIntersectionEvent(Plan.Vertex searchVertex) { var vertex = searchVertex; do { if (!vertex.inEvent && vertex != searchVertex && IncidentalVertices(searchVertex, vertex)) { var intersectionEvent = new IntersectionEvent(searchVertex.position); ExpandEvent(intersectionEvent, searchVertex); return(intersectionEvent); } vertex = vertex.next; } while (vertex != searchVertex); return(null); }
private void ExpandEvent(IntersectionEvent intersectionEvent, Plan.Vertex startVertex) { var vertex = startVertex; do { if (!vertex.inEvent && IncidentalVertices(intersectionEvent.position, vertex.position)) { var chain = FindCollapsedChain(vertex); intersectionEvent.chains.Add(chain); vertex = chain[chain.Count - 1].next; } else { vertex = vertex.next; } } while (vertex != startVertex); }
private void CreateSplitVertices(Plan plan, Plan.Vertex searchVertex) { var vertex = searchVertex; do { if (vertex != searchVertex && vertex.next != searchVertex && PointSegment(searchVertex.position, vertex.position, vertex.next.position)) { var newVertex = CreateSplitVertex(plan, searchVertex.position, vertex, vertex.next); vertex = newVertex.next; } else { vertex = vertex.next; } } while (vertex != searchVertex); }
private List <Plan.Vertex> FindCollapsedChain(Plan.Vertex startVertex) { startVertex.inEvent = true; var chain = new List <Plan.Vertex> { startVertex }; var vertex = startVertex; do { if (!vertex.next.inEvent && IncidentalVertices(vertex, vertex.next)) { vertex.next.inEvent = true; chain.Add(vertex.next); vertex = vertex.next; } else { break; } } while (vertex != startVertex); return(chain); }
private static bool IncidentalVertices(Plan.Vertex a, Plan.Vertex b) { return(IncidentalVertices(a.position, b.position)); }
private static float GetBisectorBisectorOffset(Plan.Vertex vertex, float toIntersection) { return(toIntersection * Geometry.GetAngleBisectorSin(vertex.angle)); }
private static float GetBisectorBisectorOffset(Plan.Vertex vertex, Vector2 intersection) { float toIntersection = Vector2.Distance(vertex.position, intersection); return(GetBisectorBisectorOffset(vertex, toIntersection)); }