/// <summary> Translates the hyperbolic tree by the given vector. /// </summary> /// <param name="zs">The first coordinates.</param> /// <param name="ze">The second coordinates.</param> public void Translate(EuclidianVector zs, EuclidianVector ze) { EuclidianVector __zo = new EuclidianVector(_rootNodeView.OldCoordinates); __zo.X = -__zo.X; __zo.Y = -__zo.Y; EuclidianVector __zs2 = new EuclidianVector(zs); __zs2.Translate(__zo); EuclidianVector __t = new EuclidianVector(); double __de = ze.D2(); double __ds = __zs2.D2(); double __dd = 1.0 - __de * __ds; __t.X = (ze.X * (1.0 - __ds) - __zs2.X * (1.0 - __de)) / __dd; __t.Y = (ze.Y * (1.0 - __ds) - __zs2.Y * (1.0 - __de)) / __dd; if (__t.IsValid) { HyperbolicTransformation __to = new HyperbolicTransformation(); __to.Composition(__zo, __t); _rootNodeView.Transform(__to); _view.Repaint(); } }
/// <summary> Initialize a new instance of the <see cref="Controller"/> class. /// </summary> /// <param name="model"></param> public Controller(Renderer model) { _model = model; _startPoint = new EuclidianVector(); _endPoint = new EuclidianVector(); _clickPoint = new ScreenVector(); }
/* * Some complex computing formula : * * arg(z) = atan(y / x) if x > 0 * = atan(y / x) + Pi if x < 0 * * d(z) = Math.sqrt((z.x * z.x) + (z.y * z.y)) * * conj(z) = | z.x * | - z.y * * a * b = | (a.x * b.x) - (a.y * b.y) * | (a.x * b.y) + (a.y * b.x) * * a / b = | ((a.x * b.x) + (a.y * b.y)) / d(b) * | ((a.y * b.x) - (a.x * b.y)) / d(b) */ /// <summary> Multiply this coordinate by the given coordinate. /// </summary> /// <param name="z">The coord to multiply with.</param> public void Multiply(EuclidianVector z) { double __tx = _x; double __ty = _y; _x = (__tx * z._x) - (__ty * z._y); _y = (__tx * z._y) + (__ty * z._x); }
/// <summary> Restores the hyperbolic tree to its origin. /// </summary> public virtual void Restore() { EuclidianVector __orig = _nodeModel.OriginalCoordinates; _ze.X = __orig.X; _ze.Y = __orig.Y; _oldZe.Copy(_ze); }
/// <summary> Constructor. /// </summary> /// <param name="node">The encapsulated INode.</param> /// <param name="parent">The parent node.</param> /// <param name="model">The tree model using this NodeModel.</param> public NodeModel(INode node, CompositeNodeModel parent, Model model) { _node = node; _parent = parent; _model = model; model.IncrementNumberOfNodes(); _z = new EuclidianVector(); }
/// <summary> Divide this coordinate by the given coordinate. /// </summary> /// <param name="z">The coord to divide with.</param> public void Divide(EuclidianVector z) { double d = z.D2(); double tx = _x; double ty = _y; _x = ((tx * z._x) + (ty * z._y)) / d; _y = ((ty * z._x) - (tx * z._y)) / d; }
/// <summary> Translates this node by the given vector. /// </summary> /// <param name="t">The translation vector.</param> public override void Translate(EuclidianVector t) { base.Translate(t); foreach (NodeView child in _childNodes) { child.Translate(t); Geodesic __geodesic = _geodesics[child]; if (__geodesic != null) { __geodesic.Rebuild(); } } }
private ScreenVector _c = null; // control point (on the screen) #endregion #region Constructor /// <summary> Constructor. /// </summary> /// <param name="za">The first point.</param> /// <param name="zb">The second point.</param> public Geodesic(EuclidianVector za, EuclidianVector zb) { _za = za; _zb = zb; _zc = new EuclidianVector(); _zo = new EuclidianVector(); _a = new ScreenVector(); _b = new ScreenVector(); _c = new ScreenVector(); this.Rebuild(); }
private EuclidianVector _zo = null; // center of the geodesic; #endregion Fields #region Constructors /// <summary> Constructor. /// </summary> /// <param name="za">The first point.</param> /// <param name="zb">The second point.</param> public Geodesic(EuclidianVector za, EuclidianVector zb) { _za = za; _zb = zb; _zc = new EuclidianVector(); _zo = new EuclidianVector(); _a = new ScreenVector(); _b = new ScreenVector(); _c = new ScreenVector(); this.Rebuild(); }
/// <summary> Compose the 2 given vectors translations into one given transformation. /// </summary> /// <param name="first"></param> /// <param name="second"></param> public void Composition(EuclidianVector v1, EuclidianVector v2) { _p.X = v1.X + v2.X; _p.Y = v1.Y + v2.Y; EuclidianVector __d = new EuclidianVector(v2); __d.Y = -__d.Y; __d.Multiply(v1); __d.X += 1; _p.Divide(__d); _o.X = v1.X; _o.Y = -v1.Y; _o.Multiply(v2); _o.X += 1; _o.Divide(__d); }
/// <summary> Translate this Euclidian point by the coordinates of the given Euclidian point. /// </summary> /// <param name="t">The translation coordinates.</param> public void Translate(EuclidianVector t) { // z = (z + t) / (1 + z * conj(t)) // first the denominator double __denX = (_x * t._x) + (_y * t._y) + 1; double __denY = (_y * t._x) - (_x * t._y); double __dd = (__denX * __denX) + (__denY * __denY); // and the numerator double __numX = _x + t._x; double __numY = _y + t._y; // then the division _x = ((__numX * __denX) + (__numY * __denY)) / __dd; _y = ((__numY * __denX) - (__numX * __denY)) / __dd; }
/// <summary> /// Transform this node by the given transformation. /// </summary> /// <param name="t">The transformation.</param> public void Transform(HyperbolicTransformation t) { EuclidianVector __z = new EuclidianVector(this); Multiply(t.O); _x += t.P._x; _y += t.P._y; EuclidianVector __d = new EuclidianVector(t.P); __d._y = -__d._y; __d.Multiply(__z); __d.Multiply(t.O); __d._x += 1; this.Divide(__d); }
/// <summary> Layout this node in the hyperbolic space. /// First set the point at the right distance, then translate by father's coordinates. /// Then, compute the right angle and the right width. /// </summary> /// <param name="angle">The angle from the x axis</param> /// <param name="width">The angular width to divide, / 2</param> /// <param name="length">The parent-child length.</param> public virtual void Layout(double angle, double width, double length) { // Nothing to do for the root node if (_parent == null) { return; } EuclidianVector __zp = _parent.OriginalCoordinates; // We first start as if the parent was the origin. // We still are in the hyperbolic space. _z.X = length * Math.Cos(angle); _z.Y = length * Math.Sin(angle); // Then translate by parent's coordinates _z.Translate(__zp); }
private bool _active = false; // should be drawed ? #endregion #region Constructor /// <summary> Constructor. /// </summary> /// <param name="parentNode">The father of this node.</param> /// <param name="nodeModel">The encapsulated <see cref="NodeModel"/>.</param> /// <param name="renderer">The drawing model.</param> public NodeView(CompositeNodeView parentNode, NodeModel nodeModel, Renderer renderer) { _parentNode = parentNode; _nodeModel = nodeModel; _renderer = renderer; this.Opacity = 0.9; this.Child = new NodeLabel(this); _ze = new EuclidianVector(nodeModel.OriginalCoordinates); _oldZe = new EuclidianVector(_ze); _screenCoordinates = new ScreenVector(); // store this object in INode -> NodeView mapping renderer.MapNode(nodeModel.Node, this); renderer.Children.Add(this); }
private EuclidianVector _ze = null; // current euclidian coordinates #endregion Fields #region Constructors /// <summary> Constructor. /// </summary> /// <param name="parentNode">The father of this node.</param> /// <param name="nodeModel">The encapsulated <see cref="NodeModel"/>.</param> /// <param name="renderer">The drawing model.</param> public NodeView(CompositeNodeView parentNode, NodeModel nodeModel, Renderer renderer) { _parentNode = parentNode; _nodeModel = nodeModel; _renderer = renderer; this.Opacity = 0.9; this.Child = new NodeLabel(this); _ze = new EuclidianVector(nodeModel.OriginalCoordinates); _oldZe = new EuclidianVector(_ze); _screenCoordinates = new ScreenVector(); // store this object in INode -> NodeView mapping renderer.MapNode(nodeModel.Node, this); renderer.Children.Add(this); }
/// <summary> Layout this node and its children in the hyperbolic space. /// Mainly, divide the width angle between children and put the children at the right angle. /// Compute also an optimized length to the children. /// </summary> /// <param name="angle"> The angle from the x axis.</param> /// <param name="width">The angular width to divide. / 2</param> /// <param name="length">The parent-child length.</param> public override void Layout(double angle, double width, double length) { base.Layout(angle, width, length); if (Parent != null) { // Compute the new starting angle // e(i a) = T(z)oT(zp) (e(i angle)) EuclidianVector __a = new EuclidianVector(Math.Cos(angle), Math.Sin(angle)); EuclidianVector __nz = new EuclidianVector(-Z.X, -Z.X); __a.Translate(Parent.OriginalCoordinates); __a.Translate(__nz); angle = __a.Arg(); // Compute the new width // e(i w) = T(-length) (e(i width)) // decomposed to do it faster :-) double __c = Math.Cos(width); double __A = 1 + length * length; double __B = 2 * length; width = Math.Acos((__A * __c - __B) / (__A - __B * __c)); } EuclidianVector __dump = new EuclidianVector(); int __nbrChild = _children.Count; double __l1 = (0.95 - Model.Length); double __l2 = Math.Cos((20.0 * Math.PI) / (2.0 * __nbrChild + 38.0)); length = Model.Length + (__l1 * __l2); double __startAngle = angle - width; // It may be interesting to sort children by weight instead foreach (NodeModel child in _children) { double __percent = child.Weight / _globalWeight; double __childWidth = width * __percent; double __childAngle = __startAngle + __childWidth; child.Layout(__childAngle, __childWidth, length); __startAngle += 2.0 * __childWidth; } }
/// <summary> Constructor copying the given screen point. /// </summary> /// <param name="z">The screen point to copy.</param> public EuclidianVector(EuclidianVector z) { this.Copy(z); }
/// <summary> Translates this node by the given vector. /// </summary> /// <param name="t">The translation vector.</param> public virtual void Translate(EuclidianVector t) { _ze.Translate(_oldZe, t); }
/// <summary> Copy the given HtCoordE into this HtCoordE. /// </summary> /// <param name="z">The HtCoordE to copy.</param> public void Copy(EuclidianVector z) { _x = z._x; _y = z._y; }
/// <summary> Returns the distance from this point to the point given in parameter. /// </summary> /// <param name="p">The other point.</param> /// <returns>The distance between the 2 points.</returns> public double D(EuclidianVector p) { return(Math.Sqrt((p._x - _x) * (p._x - _x) + (p._y - _y) * (p._y - _y))); }
/// <summary> Substracts the second coord to the first one and put the result in this EuclidianVector (this = a - b). /// </summary> /// <param name="a">The first coord.</param> /// <param name="b">The second coord.</param> public void Sub(EuclidianVector a, EuclidianVector b) { _x = a._x - b._x; _y = a._y - b._y; }
/// <summary> Adds the second coord to the first one and put the result in this EuclidianVector (this = a - b). /// </summary> /// <param name="a">The first coord.</param> /// <param name="b">The second coord.</param> public void Add(EuclidianVector a, EuclidianVector b) { _x = a._x + b._x; _y = a._y + b._y; }
/// <summary> Projects the given Euclidian point on the screen plane. /// </summary> /// <param name="ze">The euclidian point.</param> /// <param name="sOrigin">The origin of the screen plane.</param> /// <param name="sMax">The (xMax, yMax) point in the screen plane.</param> public void ProjectionEtoS(EuclidianVector ze, ScreenVector sOrigin, ScreenVector sMax) { _x = (int)Math.Round(ze.X * sMax._x) + sOrigin._x; _y = -(int)Math.Round(ze.Y * sMax._y) + sOrigin._y; }
private EuclidianVector _p = null; // translation vector #endregion Fields #region Constructors /// <summary> Constructor. /// </summary> public HyperbolicTransformation() { _p = new EuclidianVector(); _o = new EuclidianVector(); }
/// <summary> Translate the hyperbolic tree /// so that the given node is put at the origin of the hyperbolic tree. /// </summary> /// <param name="node">The given <see cref="HtDrawNode"/></param> public void TranslateToOrigin(NodeView node) { _view.StopMouseListening(); _velocity = new EuclidianVector(node.Coordinates); _animatedNode = node; }
/// <summary>Translate the given Euclidian point by the coordinates of the given translation vector, and put the results in this point. /// </summary> /// <param name="s">The source point.</param> /// <param name="t">The translation vector.</param> public void Translate(EuclidianVector s, EuclidianVector t) { this.Copy(s); this.Translate(t); }
private EuclidianVector _o = null; // rotation vector #endregion #region ctor /// <summary> Constructor. /// </summary> public HyperbolicTransformation() { _p = new EuclidianVector(); _o = new EuclidianVector(); }
/// <summary> Returns the distance from this point to the point given in parameter. /// </summary> /// <param name="p">The other point.</param> /// <returns>The distance between the 2 points.</returns> public double D(EuclidianVector p) { return Math.Sqrt((p._x - _x) * (p._x - _x) + (p._y - _y) * (p._y - _y)); }