Пример #1
0
        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;
        }