public void GenerateImage(Link link, string faction1, string faction2, string offensiveFaction)
 {
     var fileName = link.GetFileName(Galaxy, faction1, faction2, offensiveFaction);
     var linkDrawing = GetLinkDrawing(link, faction1, faction2, offensiveFaction);
     if (linkDrawing != null && !File.Exists(fileName)) {
         var bitmapSize = GetImageBounds(link).Size.Multiply(AntiAliasFactor);
         using (var bitmap = new Bitmap(bitmapSize.Width, bitmapSize.Height)) {
             var location = new Point(Padding*AntiAliasFactor, Padding*AntiAliasFactor);
             using (var g = Graphics.FromImage(bitmap)) {
                 SetHighQuality(g);
                 linkDrawing.Draw(g, location, MapSize.Multiply(AntiAliasFactor));
             }
             bitmap.HighQualityResize(1/(float)AntiAliasFactor).Save(
                 Path.Combine(ImagePath, fileName), ImageFormat);
         }
     }
 }
		void AddLink(PointF locationF)
		{
			if (GalaxyMap.Instance.PlanetDrawings.Count < 2) {
				return;
			}
			if (selectedPlanetDrawing == null) {
				selectedPlanetDrawing = locationF.FindClosest(GalaxyMap.Instance.PlanetDrawings);
				Redraw();
			} else {
				var planetDrawing = locationF.FindClosest(GalaxyMap.Instance.PlanetDrawings);
				if (
					!GalaxyMap.Instance.Galaxy.Links.Any(
					 	l =>
					 	GalaxyMap.Instance.Galaxy.GetPlanets(l).Contains(planetDrawing.Planet) &&
					 	GalaxyMap.Instance.Galaxy.GetPlanets(l).Contains(selectedPlanetDrawing.Planet))) {
					var link = new Link(selectedPlanetDrawing.Planet.ID, planetDrawing.Planet.ID);
					GalaxyMap.Instance.Galaxy.Links.Add(link);
					selectedPlanetDrawing = null;
					Redraw();
				}
			}
		}
		public void DrawLink(Graphics g, Link link, Color color, Size mapSize)
		{
            using (var pen = new Pen(color, 2) { DashStyle = DashStyle.DashDot, LineJoin = LineJoin.Round, }) {
                var planets = GalaxyMap.Instance.Galaxy.GetPlanets(link).ToArray();
                g.DrawLine(pen, planets[0].Position.Scale(mapSize), planets[1].Position.Scale(mapSize));
            }
		}
        public LinkDrawing GetLinkDrawing(Link link, string faction1, string faction2, string offensiveFaction)
        {
            var planets = link.PlanetIDs.Select(id => Galaxy.GetPlanet(id)).ToArray();
            var factionNames = new[] { faction1, faction2 };

            if (!DrawLinksBetweenNeutralPlanets && factionNames.All(f => f == null)) {
                return null;
            }

            var isColonyLink = factionNames.Contains(null);

            var isArrowNeeded = factionNames[0] != factionNames[1] &&
                                (isColonyLink || factionNames.Contains(offensiveFaction));

            var points = planets.Select(p => p.Position).ToArray();
            var colors = factionNames.Select(f => f == null ? neutralColor : Galaxy.GetFaction(f).Color).ToArray();

            var linkDrawing = new LinkDrawing();

            if (isArrowNeeded) {
                var arrowTipIndex = Array.FindIndex(factionNames, f => isColonyLink ? f == null : f != offensiveFaction);
                var arrowEndIndex = arrowTipIndex == 0 ? 1 : 0;

                linkDrawing.IsArrow = true;
                linkDrawing.IsColonyLink = isColonyLink;

                linkDrawing.Tip = points[arrowTipIndex];
                linkDrawing.End = points[arrowEndIndex];
                linkDrawing.TipColor = colors[arrowTipIndex];
                linkDrawing.EndColor = colors[arrowEndIndex];

                // shorten the arrow so the tip isn't covered by a planet
                linkDrawing.ArrowOffset = ArrowOffset * AntiAliasFactor;
            } else {
                // doesn't matter which is the tip
                linkDrawing.Tip = points[0];
                linkDrawing.End = points[1];
                linkDrawing.TipColor = colors[0];
                linkDrawing.EndColor = colors[1];
            }

            linkDrawing.Location = PointF.Empty;
            var galaxySize = Program.MainForm.MapBox.Image.Width;
            linkDrawing.LineWidth = LineWidth / galaxySize;

            return linkDrawing;
        }
 public Rectangle GetImageBounds(Link link)
 {
     var planetPositions = Galaxy.GetPlanets(link).Select(p => p.Position).ToArray();
     planetPositions = planetPositions.Select(p => p.Scale(MapSize)).ToArray(); // to image coords
     return planetPositions.ToRectangleF().ToRectangle().PadRectangle(Padding);
 }
 public ICollection<Planet> GetPlanets(Link link)
 {
     return (from id in link.PlanetIDs
             join p in Planets on id equals p.ID
             select p).ToArray();
 }