public static double AngleBetween(Vector vector1, Vector vector2)
        {
            if (vector1 == vector2)
            {
                return(0);
            }
            vector1 = vector1.GetNormalized();
            vector2 = vector2.GetNormalized();
            double cos   = DotProduct(vector1, vector2);
            double sin   = CrossProduct(vector1, vector2);
            double angle = Math.Atan2(sin, cos);

            return(angle);
        }
 public static double AngleBetween(Vector vector1, Vector vector2)
 {
     if (vector1 == vector2)
         return 0;
     vector1 = vector1.GetNormalized();
     vector2 = vector2.GetNormalized();
     double cos = DotProduct(vector1, vector2);
     double sin = CrossProduct(vector1, vector2);
     double angle = Math.Atan2(sin, cos);
     return angle;
 }
        public Shape FitMeanShape(int width, int height, Vector rootEdgeDirection)
        {
            rootEdgeDirection = rootEdgeDirection.GetNormalized();
            
            // Build tree with a root edge scale
            Vector[] vertices = new Vector[this.Structure.VertexCount];
            vertices[this.Structure.Edges[this.rootEdgeIndex].Index1] = new Vector(0, 0);
            vertices[this.Structure.Edges[this.rootEdgeIndex].Index2] = rootEdgeDirection * this.RootEdgeMeanLength;
            foreach (int childEdgeIndex in this.IterateNeighboringEdgeIndices(this.rootEdgeIndex))
            {
                BuildShapeFromLengthAngleRepresentationDfs(
                    vertices,
                    childEdgeIndex,
                    this.rootEdgeIndex,
                    vertices[this.Structure.Edges[this.rootEdgeIndex].Index1],
                    vertices[this.Structure.Edges[this.rootEdgeIndex].Index2],
                    (currentEdge, parentEdge, parentLength) => parentLength / this.GetEdgePairParams(parentEdge, currentEdge).MeanLengthRatio,
                    (currentEdge, parentEdge, parentAngle) => parentAngle + this.GetEdgePairParams(parentEdge, currentEdge).MeanAngle);
            }

            // Determine axis-aligned bounding box for the generated shapes
            Vector min = new Vector(Double.PositiveInfinity, Double.PositiveInfinity);
            Vector max = new Vector(Double.NegativeInfinity, Double.NegativeInfinity);
            for (int i = 0; i < this.Structure.VertexCount; ++i)
            {
                min.X = Math.Min(min.X, vertices[i].X);
                min.Y = Math.Min(min.Y, vertices[i].Y);
                max.X = Math.Max(max.X, vertices[i].X);
                max.Y = Math.Max(max.Y, vertices[i].Y);
            }
            Vector center = 0.5 * (min + max);

            // Shift vertices to the center of image
            for (int i = 0; i < this.Structure.VertexCount; ++i)
            {
                Vector pos = vertices[i];
                pos -= center;
                pos += new Vector(width * 0.5, height * 0.5);
                vertices[i] = pos;
            }

            // Generate best possible edge widths
            List<double> edgeWidths = new List<double>();
            for (int i = 0; i < this.edgeParams.Count; ++i)
            {
                ShapeEdge edge = this.Structure.Edges[i];
                double length = (vertices[edge.Index1] - vertices[edge.Index2]).Length;
                edgeWidths.Add(length * this.edgeParams[i].WidthToEdgeLengthRatio);
            }

            return new Shape(this.Structure, vertices, edgeWidths);
        }