public Vector3 GetElementPositionWithoutColliding(ICircleElement element, Vector3 oldPosition, Vector3 newPosition) { var allButMe = decoSpaceIndex.GetElements(newPosition).Where(e => e != element).ToList(); newPosition = allButMe.Aggregate(newPosition, (current, circleElement) => PushPositionAway(current, element.CircleElementProperties.Radius, (ICircleElement)circleElement)); return(!CanMoveWithoutCollision(element, newPosition) ? oldPosition : newPosition); //If still collision after correction => Don't move }
public bool MoveDetectCollision(ICircleElement element, Vector3 previousPosition, Vector3 Position) { var oldBasePosition = decoSpaceIndex.GetBasePosition(previousPosition); var newBasePosition = decoSpaceIndex.GetBasePosition(Position); if (oldBasePosition != newBasePosition) { decoSpaceIndex.MoveElementBetweenChunks(element, oldBasePosition, newBasePosition); } return(decoSpaceIndex.GetElements(Position).Any(e => collide((ICircleElement)e, element, Position))); }
public Vector3 PushPositionAway(Vector3 Position, float radius, ICircleElement other) { if (radius == 0f || other.CircleElementProperties.Radius == 0f) { return(Position); } var otherRad = other.CircleElementProperties.Radius; var distance = Position - other.IndexPosition; var sqrMagnitude = distance.sqrMagnitude; var totalRadius = otherRad + radius; if (sqrMagnitude > totalRadius * totalRadius) { return(Position); } return(other.IndexPosition + (totalRadius + 0.01f) * distance.normalized); }
private bool collide(ICircleElement a, ICircleElement b, Vector3 bPosition) { if (a == b) { return(false); } if (a.CircleElementProperties == null) { return(false); } if (b.CircleElementProperties == null) { return(false); } if (a.CircleElementProperties.Radius == 0f || b.CircleElementProperties.Radius == 0f) { return(false); } return((a.IndexPosition - bPosition).sqrMagnitude < (a.CircleElementProperties.Radius + b.CircleElementProperties.Radius) * (a.CircleElementProperties.Radius + b.CircleElementProperties.Radius)); }
/// <summary> /// 添加图元 /// </summary> /// <param name="pGeometry"></param> /// <param name="pActiveView"></param> /// <param name="pSymbol"></param> /// <param name="key"></param> /// <returns></returns> public IElement AddElement(IGeometry pGeometry, ISymbol pSymbol, string key) { try { IActiveView pActiveView = mapControl.ActiveView; IGraphicsContainer pGraphicsContainer = pActiveView.GraphicsContainer; IElement pElement = null; ILineElement pLineElement = null; IFillShapeElement pFillShapeElement = null; IMarkerElement pMarkerElement = null; ICircleElement pCircleElement = null; IElementProperties pElmentProperties = null; switch (pGeometry.GeometryType) { case esriGeometryType.esriGeometryEnvelope: { pElement = new RectangleElement(); pElement.Geometry = pGeometry; pFillShapeElement = (IFillShapeElement)pElement; pFillShapeElement.Symbol = (IFillSymbol)pSymbol; break; } case esriGeometryType.esriGeometryPolyline: { pElement = new LineElement(); pElement.Geometry = pGeometry; pLineElement = (ILineElement)pElement; pLineElement.Symbol = (ILineSymbol)pSymbol; break; } case esriGeometryType.esriGeometryLine: { pElement = new LineElement(); pElement.Geometry = pGeometry; pLineElement = (ILineElement)pElement; pLineElement.Symbol = (ILineSymbol)pSymbol; break; } case esriGeometryType.esriGeometryPolygon: { pElement = new PolygonElement(); pElement.Geometry = pGeometry; pFillShapeElement = (IFillShapeElement)pElement; pFillShapeElement.Symbol = (IFillSymbol)pSymbol; break; } case esriGeometryType.esriGeometryMultipoint: case esriGeometryType.esriGeometryPoint: { pElement = new MarkerElement(); pElement.Geometry = pGeometry; pMarkerElement = (IMarkerElement)pElement; pMarkerElement.Symbol = (IMarkerSymbol)pSymbol; break; } case esriGeometryType.esriGeometryCircularArc: { pElement = new CircleElement(); pElement.Geometry = pGeometry; pCircleElement = (ICircleElement)pElement; break; } default: pElement = null; break; } if (pElement != null) { pElmentProperties = pElement as IElementProperties; pElmentProperties.Name = key; pGraphicsContainer.AddElement(pElement, 0); pActiveView.PartialRefresh(esriViewDrawPhase.esriViewBackground, null, pGeometry.Envelope); return(pElement); } else { return(null); } } catch (Exception ex) { return(null); } }
public void Move(ICircleElement element, Vector3 Position) { decoSpaceIndex.Move(element, Position); }
public List <ICircleElement> GetColliders(ICircleElement element, Vector3 Position) { return(decoSpaceIndex.GetElements(Position).Where(e => collide((ICircleElement)e, element, Position)).Select(e => (ICircleElement)e).ToList()); }
public bool CanMoveWithoutCollision(ICircleElement element, Vector3 Position) { return(!decoSpaceIndex.GetElements(Position).Any(e => collide((ICircleElement)e, element, Position))); }