예제 #1
0
        private static DecorationSpot GetPosition(PointF[] points, double pathLength, int start, int end)
        {
            double         lenSqr     = 0;
            double         pathLenSqr = pathLength * pathLength;
            DecorationSpot result     = new DecorationSpot();

            for (int i = start; i < end; i++)
            {
                double dx = points[i + 1].X - points[i].X;
                double dy = points[i + 1].Y - points[i].Y;
                lenSqr += dx * dx + dy * dy;
                if (pathLenSqr >= lenSqr)
                {
                    continue;
                }
                double segLen  = Math.Sqrt(dx * dx + dy * dy);
                double backLen = Math.Sqrt(lenSqr) - Math.Sqrt(pathLenSqr);
                double rat     = backLen / segLen;
                float  x       = (float)(points[i + 1].X - rat * dx);
                float  y       = (float)(points[i + 1].Y - rat * dy);

                result.Position = new PointF(x, y);
                result.Before   = points[i];
                result.After    = points[i + 1];
                return(result);
            }
            return(result);
        }
예제 #2
0
        private static DecorationSpot GetPosition(PointF[] points, double pathLength, int start, int end)
        {
            double lenSqr = 0;
            double pathLenSqr = pathLength * pathLength;
            DecorationSpot result = new DecorationSpot();
            for (int i = start; i < end; i++)
            {
                double dx = points[i + 1].X - points[i].X;
                double dy = points[i + 1].Y - points[i].Y;
                lenSqr += dx * dx + dy * dy;
                if (pathLenSqr >= lenSqr) continue;
                double segLen = Math.Sqrt(dx * dx + dy * dy);
                double backLen = Math.Sqrt(lenSqr) - Math.Sqrt(pathLenSqr);
                double rat = backLen / segLen;
                float x = (float)(points[i + 1].X - rat * dx);
                float y = (float)(points[i + 1].Y - rat * dy);

                result.Position = new PointF(x, y);
                result.Before = points[i];
                result.After = points[i + 1];
                return result;
            }
            return result;
        }
예제 #3
0
        /// <summary>
        /// Get the decoration spots that result from the given line and segLength. The decoration spot needed for the endpoint is not included.
        /// </summary>
        /// <param name="points">Point-Array that contains the points of the line.</param>
        /// <param name="segLength">Distance between two decoration spots.</param>
        /// <param name="start">Index of the first point that belongs to the line.</param>
        /// <param name="end">Index of the last point that belongs to the line.</param>
        /// <returns>List of decoration spots that result from the given points and segLength.</returns>
        private static List <DecorationSpot> GetPosition(PointF[] points, double segLength, int start, int end)
        {
            double coveredDistance      = 0; // distance between the last decoration spot and the line end; needed to get the correct position of the next decoration spot on the next line
            List <DecorationSpot> liste = new List <DecorationSpot>();

            for (int i = start; i < end; i++)
            {
                if (coveredDistance == 0)
                {
                    // startpoint of the first line or last segment ended on startpoint of next line
                    DecorationSpot result = new DecorationSpot(points[i], points[i + 1], points[i]);
                    liste.Add(result);
                    coveredDistance = 0;
                    if (double.IsInfinity(segLength))
                    {
                        return(liste);                              // when segLength is infinit we're looking only for the first decoration spot
                    }
                }

                double dx         = points[i + 1].X - points[i].X;
                double dy         = points[i + 1].Y - points[i].Y;
                double lineLength = Math.Sqrt(dx * dx + dy * dy);
                if (coveredDistance + lineLength <= segLength)
                {
                    coveredDistance += lineLength;
                    continue; // line was shorter than segment -> does not contain any decorations
                }

                double offset = segLength - coveredDistance; // offset of the first decoration spot

                if (dx == 0)
                {
                    // line is parallel to y-axis
                    while (Math.Round(offset, 3) < Math.Round(lineLength, 3))
                    {
                        float x = points[i].X;
                        float y;
                        if (points[i].Y > points[i + 1].Y)
                        {
                            // line goes bottom up
                            y = (float)(points[i].Y - offset);
                        }
                        else
                        {
                            // line goes top down
                            y = (float)(points[i].Y + offset);
                        }

                        liste.Add(new DecorationSpot(points[i], points[i + 1], new PointF(x, y)));
                        offset += segLength;
                    }

                    if (Math.Round(offset, 3) > Math.Round(lineLength, 3))
                    {
                        var lastpnt = liste[liste.Count - 1];
                        coveredDistance = GetLength(lastpnt.Position, lastpnt.After);
                    }
                    else
                    {
                        coveredDistance = 0; // segment ends on endpoint of the current line -> reset coveredDistance to add a decoration spot at the beginning of the next line
                    }
                }
                else
                {
                    // line is not parallel to y-axis
                    double slope = dy / dx;
                    double alpha = Math.Atan(slope);

                    while (Math.Round(offset, 3) < Math.Round(lineLength, 3))
                    {
                        float x, y;
                        if (points[i].X < points[i + 1].X)
                        {
                            // line goes right to left
                            x = (float)(points[i].X + Math.Cos(alpha) * offset);
                            y = (float)(points[i].Y + Math.Sin(alpha) * offset);
                        }
                        else
                        {
                            // line goes left to right
                            x = (float)(points[i].X - Math.Cos(alpha) * offset);
                            y = (float)(points[i].Y - Math.Sin(alpha) * offset);
                        }

                        var newPoint = new PointF(x, y);
                        liste.Add(new DecorationSpot(points[i], points[i + 1], newPoint));
                        offset += segLength;
                    }

                    if (Math.Round(offset, 3) > Math.Round(lineLength, 3))
                    {
                        var lastpnt = liste[liste.Count - 1];
                        coveredDistance = GetLength(lastpnt.Position, lastpnt.After);
                    }
                    else
                    {
                        coveredDistance = 0; // segment ends on endpoint of the current line -> reset coveredDistance to add a decoration spot at the beginning of the next line
                    }
                }
            }

            return(liste);
        }
예제 #4
0
        /// <summary>
        /// Given the points on this line decoration, this will cycle through and handle
        /// the drawing as dictated by this decoration.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="path"></param>
        /// <param name="scaleWidth">The double scale width for controling markers</param>
        public void Draw(Graphics g, GraphicsPath path, double scaleWidth)
        {
            if (NumSymbols == 0)
            {
                return;
            }
            GraphicsPathIterator myIterator = new GraphicsPathIterator(path);

            myIterator.Rewind();
            int      start, end;
            bool     isClosed;
            Size2D   symbolSize = _symbol.GetSize();
            Bitmap   symbol     = new Bitmap((int)symbolSize.Width, (int)symbolSize.Height);
            Graphics sg         = Graphics.FromImage(symbol);

            _symbol.Draw(sg, new Rectangle(0, 0, (int)symbolSize.Width, (int)symbolSize.Height));
            sg.Dispose();

            Matrix oldMat = g.Transform;

            PointF[] points;
            if (path.PointCount == 0)
            {
                return;
            }
            try
            {
                points = path.PathPoints;
            }
            catch
            {
                return;
            }
            PointF offset;

            int count = 0;

            while (myIterator.NextSubpath(out start, out end, out isClosed) > 0)
            {
                count = count + 1;
                // First marker
                PointF startPoint = points[start];
                PointF stopPoint  = points[start + 1];
                float  angle      = 0F;
                if (_rotateWithLine)
                {
                    angle = GetAngle(startPoint, stopPoint);
                }
                if (FlipFirst && !FlipAll)
                {
                    FlipAngle(ref angle);
                }
                offset     = GetOffset(startPoint, stopPoint);
                startPoint = new PointF(startPoint.X + offset.X, startPoint.Y + offset.Y);
                Matrix rotated = g.Transform;
                rotated.RotateAt(angle, startPoint);
                g.Transform = rotated;
                DrawImage(g, startPoint, symbol);
                g.Transform = oldMat;

                // Second marker
                if (NumSymbols > 1)
                {
                    angle = 0F;
                    if (_rotateWithLine)
                    {
                        angle = GetAngle(points[end - 1], points[end]);
                    }
                    if (FlipAll)
                    {
                        FlipAngle(ref angle);
                    }
                    offset = GetOffset(points[end - 1], points[end]);
                    PointF endPoint = new PointF(points[end].X + offset.X, points[end].Y + offset.Y);
                    rotated = g.Transform;
                    rotated.RotateAt(angle, endPoint);
                    g.Transform = rotated;
                    DrawImage(g, endPoint, symbol);
                    g.Transform = oldMat;
                }
                if (NumSymbols > 2)
                {
                    double totalLength = GetLength(points, start, end);
                    double span        = totalLength / (NumSymbols - 1);
                    for (int i = 1; i < NumSymbols - 1; i++)
                    {
                        DecorationSpot spot = GetPosition(points, span * i, start, end);
                        angle = 0F;
                        if (_rotateWithLine)
                        {
                            angle = GetAngle(spot.Before, spot.After);
                        }
                        offset = GetOffset(spot.Before, spot.After);
                        PointF location = new PointF(spot.Position.X + offset.X, spot.Position.Y + offset.Y);
                        if (FlipAll)
                        {
                            FlipAngle(ref angle);
                        }
                        rotated = g.Transform;
                        rotated.RotateAt(angle, location);
                        g.Transform = rotated;
                        DrawImage(g, location, symbol);
                        g.Transform = oldMat;
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Get the decoration spots that result from the given line and segLength. The decoration spot needed for the endpoint is not included.
        /// </summary>
        /// <param name="points">Point-Array that contains the points of the line.</param>
        /// <param name="segLength">Distance between two decoration spots.</param>
        /// <param name="start">Index of the first point that belongs to the line.</param>
        /// <param name="end">Index of the last point that belongs to the line.</param>
        /// <returns>List of decoration spots that result from the given points and segLength.</returns>
        private List<DecorationSpot> GetPosition(PointF[] points, double segLength, int start, int end)
        {
            double coveredDistance = 0; //distance between the last decoration spot and the line end; needed to get the correct position of the next decoration spot on the next line
            List<DecorationSpot> liste = new List<DecorationSpot>();

            for (int i = start; i < end; i++)
            {
                if (coveredDistance == 0) //startpoint of the first line or last segment ended on startpoint of next line
                {
                    DecorationSpot result = new DecorationSpot();
                    result.Position = points[i];
                    result.Before = points[i];
                    result.After = points[i + 1];
                    liste.Add(result);
                    coveredDistance = 0;
                    if (double.IsInfinity(segLength)) return liste; // when segLength is infinit we're looking only for the first decoration spot
                }

                double dx = points[i + 1].X - points[i].X;
                double dy = points[i + 1].Y - points[i].Y;
                double lineLength = Math.Sqrt(dx * dx + dy * dy);
                if (coveredDistance + lineLength <= segLength)
                {
                    coveredDistance += lineLength;
                    continue; // line was shorter than segment -> does not contain any decorations
                }

                double offset = segLength - coveredDistance; // offset of the first decoration spot

                if (dx == 0) // line is parallel to y-axis
                {
                    while (Math.Round(offset, 3) < Math.Round(lineLength, 3))
                    {
                        float x = points[i].X;
                        float y;
                        if (points[i].Y > points[i + 1].Y) // line goes bottom up
                        {
                            y = (float)(points[i].Y - offset);
                        }
                        else // line goes top down
                        {
                            y = (float)(points[i].Y + offset);
                        }

                        liste.Add(new DecorationSpot(points[i], points[i + 1], new PointF(x, y)));
                        offset += segLength;
                    }
                    if (Math.Round(offset, 3) > Math.Round(lineLength, 3))
                    {
                        var lastpnt = liste[liste.Count - 1];
                        coveredDistance = GetLength(lastpnt.Position, lastpnt.After);
                    }
                    else
                    {
                        coveredDistance = 0; // segment ends on endpoint of the current line -> reset coveredDistance to add a decoration spot at the beginning of the next line
                    }
                }
                else // line is not parallel to y-axis
                {
                    double slope = dy / dx;
                    double alpha = Math.Atan(slope);

                    while (Math.Round(offset, 3) < Math.Round(lineLength, 3))
                    {
                        float x, y;
                        if (points[i].X < points[i + 1].X) // line goes right to left
                        {
                            x = (float)(points[i].X + Math.Cos(alpha) * offset);
                            y = (float)(points[i].Y + Math.Sin(alpha) * offset);
                        }
                        else // line goes left to right
                        {
                            x = (float)(points[i].X - Math.Cos(alpha) * offset);
                            y = (float)(points[i].Y - Math.Sin(alpha) * offset);
                        }

                        var newPoint = new PointF(x, y);
                        liste.Add(new DecorationSpot(points[i], points[i + 1], newPoint));
                        offset += segLength;
                    }
                    if (Math.Round(offset, 3) > Math.Round(lineLength, 3))
                    {
                        var lastpnt = liste[liste.Count - 1];
                        coveredDistance = GetLength(lastpnt.Position, lastpnt.After);
                    }
                    else
                    {
                        coveredDistance = 0; // segment ends on endpoint of the current line -> reset coveredDistance to add a decoration spot at the beginning of the next line
                    }
                }
            }
            return liste;
        }