#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Drawing; using HeuristicLab.Visualization; namespace HeuristicLab.EvolutionaryTracking.Views { public class VisualGenealogyGraphNode : Ellipse { public IGenealogyGraphNode Data { get; internal set; } private List _incomingArcs = new List(); private List _outgoingArgs = new List(); public List IncomingArcs { get { return _incomingArcs; } set { _incomingArcs = value; } } public List OutgoingArcs { get { return _outgoingArgs; } set { _outgoingArgs = value; } } public VisualGenealogyGraphNode(IChart chart, PointD lowerLeft, PointD upperRight) : base(chart, lowerLeft, upperRight) { } public VisualGenealogyGraphNode(IChart chart, double x1, double y1, double x2, double y2) : this(chart, new PointD(x1, y1), new PointD(x2, y2)) { } public VisualGenealogyGraphNode(IChart chart, PointD lowerLeft, PointD upperRight, Pen pen, Brush brush) : base(chart, lowerLeft, upperRight, pen, brush) { } public VisualGenealogyGraphNode(IChart chart, double x1, double y1, double x2, double y2, Pen pen, Brush brush) : this(chart, new PointD(x1, y1), new PointD(x2, y2), pen, brush) { } // compute the intersection point of an ellipse and a line passing through its center with the angular coordinate theta public PointD CalculateIntersection(double theta) { double sin = Math.Sin(theta); double cos = Math.Cos(theta); double a = Size.Width / 2; double b = Size.Height / 2; double r = a * b / Math.Sqrt(Math.Pow(a * sin, 2) + Math.Pow(b * cos, 2)); // radius at intersection point double rx = r * cos; // X-component (relative to the origin/center of the ellipse) double ry = r * sin; // Y-component (relative to the origin/center of the ellipse) return new PointD(rx, ry); } public override void SetPosition(PointD lowLeft, PointD upRight) { base.SetPosition(lowLeft, upRight); foreach (var a in IncomingArcs) a.UpdatePosition(); foreach (var a in OutgoingArcs) a.UpdatePosition(); } public PointD Center { get { return new PointD((LowerLeft.X + UpperRight.X) / 2, (LowerLeft.Y + UpperRight.Y) / 2); } } public override void Draw(Graphics graphics) { Point p = Chart.TransformWorldToPixel(new PointD(LowerLeft.X, LowerLeft.Y + Size.Height)); Size s = Chart.TransformWorldToPixel(Size); if (Brush != null) graphics.FillEllipse(Brush, p.X, p.Y, s.Width, s.Height); graphics.DrawEllipse(Pen, p.X, p.Y, s.Width, s.Height); if (((SymbolicExpressionGenealogyGraphNode)Data).IsElite) { graphics.DrawEllipse(Pen, p.X + 2, p.Y + 2, s.Width - 4, s.Height - 4); } } } }