private static bool TryDrawLineFromOverlappingLocation(OverlappedLocation OverlappingLocation, RoundLineCode.RoundLineManager lineManager, int section_number, float time_offset) { if (OverlappingLocation != null) { LocationLink SelectedLink = OverlappingLocation.link; //Give the colors a nudge towards red or blue depending on the direction to the link double directionFactor = 1; StructureType type = new StructureType(SelectedLink.A.Parent.Type); int distanceFactor = SelectedLink.maxSection - SelectedLink.minSection; if (distanceFactor == 0) distanceFactor = 1; directionFactor = SelectedLink.maxSection == section_number ? 1 : -1; int red = (int)((float)(type.Color.R * .5) + (128 * directionFactor)); red = 255 - (red / distanceFactor); red = red > 255 ? 255 : red; int blue = (int)((float)(type.Color.B * .5) + (128 * (1 - directionFactor))); blue = 255 - (blue / distanceFactor); blue = blue > 255 ? 255 : blue; int green = (int)((float)type.Color.G); green = 255 - (green / distanceFactor); int alpha = 85; if (LastMouseOverObject == SelectedLink) { alpha = 192; } //If you don't cast to byte the wrong constructor is used and the alpha value is wrong Microsoft.Xna.Framework.Color color = new Microsoft.Xna.Framework.Color((byte)(red), (byte)(green), (byte)(blue), (byte)(alpha)); lineManager.Draw(SelectedLink.lineGraphic, (float)SelectedLink.Radius, color, basicEffect.View * basicEffect.Projection, time_offset, null); return true; } return false; }
private ConcurrentDictionary<Location_CanvasCircleAnnotationViewModel, GridCircle> CalculateOverlappedLocationCircles() { ConcurrentDictionary<Location_CanvasCircleAnnotationViewModel, GridCircle> listCircles = null; if (_OverlappingLinkedLocationCircles == null) { listCircles = new ConcurrentDictionary<Location_CanvasCircleAnnotationViewModel, GridCircle>(); } else { listCircles = _OverlappingLinkedLocationCircles; listCircles.Clear(); } List<Location_CanvasCircleAnnotationViewModel> listLinksAbove = new List<Location_CanvasCircleAnnotationViewModel>(this.Links.Count); List<Location_CanvasCircleAnnotationViewModel> listLinksBelow = new List<Location_CanvasCircleAnnotationViewModel>(this.Links.Count); foreach (long linkID in Links) { LocationObj locObj = Store.Locations.GetObjectByID(linkID, false); if (locObj == null) { continue; } if (locObj.Z == this.Z) continue; Location_CanvasCircleAnnotationViewModel loc = new Location_CanvasCircleAnnotationViewModel(locObj); if (loc == null) continue; if (loc.OffSectionRadius + this.Radius < GridVector2.Distance(loc.VolumePosition, this.VolumePosition)) continue; else if (loc.Section < this.Section) { listLinksBelow.Add(loc); } else { listLinksAbove.Add(loc); } } listLinksAbove = listLinksAbove.OrderBy(L => -L.X).ThenBy(L => L.Y).ToList(); listLinksBelow = listLinksBelow.OrderBy(L => L.X).ThenBy(L => L.Y).ToList(); //Figure out how large link images would be double linkRadius = this.Radius / 6; double linkArcNormalizedDistanceFromCenter = 0.75; double linkArcDistanceFromCenter = linkArcNormalizedDistanceFromCenter * this.Radius; double circumferenceOfLinkArc = linkArcDistanceFromCenter * Math.PI; //Don't multiply by two since we only use top half of circle double UpperArcLinkRadius = linkRadius; double LowerArcLinkRadius = linkRadius; //See if we will run out of room for links if (linkRadius * listLinksAbove.Count > circumferenceOfLinkArc) { UpperArcLinkRadius = circumferenceOfLinkArc / listLinksAbove.Count; } if (linkRadius * listLinksBelow.Count > circumferenceOfLinkArc) { LowerArcLinkRadius = circumferenceOfLinkArc / listLinksBelow.Count; } double UpperArcStepSize = UpperArcLinkRadius / (circumferenceOfLinkArc / 2); double LowerArcStepSize = LowerArcLinkRadius / (circumferenceOfLinkArc / 2); //double angleOffset =((listLinksAbove.Count / 2) / (double)listLinksAbove.Count) * Math.PI; double halfNumLinksAbove = listLinksAbove.Count / 2; double angleOffset = ((double)(1 - listLinksAbove.Count) % 2) * (UpperArcStepSize / 2); for (int iLocAbove = 0; iLocAbove < listLinksAbove.Count; iLocAbove++) { Location_CanvasCircleAnnotationViewModel linkLoc = listLinksAbove[iLocAbove]; //Figure out where the link should be drawn. //Allocate the top 180 degree arc for links above, the bottom 180 for links below double angle = (((((double)iLocAbove - halfNumLinksAbove) * UpperArcStepSize) - angleOffset) * Math.PI); //- angleOffset; Vector3 positionOffset = new Vector3((float)Math.Sin(angle), (float)Math.Cos(angle), (float)0); positionOffset *= (float)linkArcDistanceFromCenter; GridCircle circle = new GridCircle(this.VolumePosition + new GridVector2(positionOffset.X, positionOffset.Y), UpperArcLinkRadius); OverlappedLocation overlapLocation = new OverlappedLocation(new LocationLink(this, linkLoc), linkLoc.modelObj, circle); bool added = listCircles.TryAdd(overlapLocation, circle); if (!added) { overlapLocation = null; linkLoc = null; } } double halfNumLinksBelow = listLinksBelow.Count / 2; angleOffset = ((double)(1 - listLinksBelow.Count) % 2) * (LowerArcStepSize / 2); for (int iLocBelow = 0; iLocBelow < listLinksBelow.Count; iLocBelow++) { Location_CanvasCircleAnnotationViewModel linkLoc = listLinksBelow[iLocBelow]; //Figure out where the link should be drawn. //Allocate the top 180 degree arc for links above, the bottom 180 for links below double angle = (((((double)iLocBelow - halfNumLinksBelow) * LowerArcStepSize) - angleOffset) * Math.PI) + Math.PI; Vector3 positionOffset = new Vector3((float)Math.Sin(angle), (float)Math.Cos(angle), (float)0); positionOffset *= (float)linkArcDistanceFromCenter; GridCircle circle = new GridCircle(this.VolumePosition + new GridVector2(positionOffset.X, positionOffset.Y), LowerArcLinkRadius); OverlappedLocation overlapLocation = new OverlappedLocation(new LocationLink(this, linkLoc), linkLoc.modelObj, circle); bool added = listCircles.TryAdd(overlapLocation, circle); if (!added) { overlapLocation = null; linkLoc = null; } } return listCircles; }