예제 #1
0
        public void RotateInPlace(RawDrawing drawing, double angleDegrees)
        {
            float minX = float.PositiveInfinity,
                  minY = float.PositiveInfinity,
                  maxX = float.NegativeInfinity,
                  maxY = float.NegativeInfinity;

            foreach (var line in drawing.Lines)
            {
                foreach (var rawPoint in line)
                {
                    minX = Math.Min(minX, rawPoint.X);
                    minY = Math.Min(minY, rawPoint.Y);
                    maxX = Math.Max(maxX, rawPoint.X);
                    maxY = Math.Max(maxY, rawPoint.Y);
                }
            }

            float ox = (minX + maxX) / 2;
            float oy = (minY + maxY) / 2;

            float sin = (float)Math.Sin(angleDegrees / 180 * Math.PI);
            float cos = (float)Math.Cos(angleDegrees / 180 * Math.PI);

            foreach (var line in drawing.Lines)
            {
                for (int i = 0; i < line.Length; ++i)
                {
                    float dx = line[i].X - ox;
                    float dy = line[i].Y - oy;
                    line[i].X = cos * dx - sin * dy + ox;
                    line[i].Y = sin * dx + cos * dy + oy;
                }
            }
        }
예제 #2
0
        public Bitmap Rasterize(RawDrawing drawing, int imageSize, float penSizePerc, bool extraMargin, bool drawPoints)
        {
            Bitmap img = new Bitmap(imageSize, imageSize, PixelFormat.Format24bppRgb);

            Rasterize(img, new Rectangle(0, 0, img.Width, img.Height), drawing, penSizePerc, extraMargin, drawPoints);
            return(img);
        }
예제 #3
0
        public RawDrawing Rotate(RawDrawing drawing, double angleDegrees)
        {
            var newDrawing = new RawDrawing(drawing);

            RotateInPlace(drawing, angleDegrees);
            return(newDrawing);
        }
예제 #4
0
        public RawDrawing Normalize(RawDrawing drawing)
        {
            var newDrawing = new RawDrawing(drawing);

            NormalizeInPlace(newDrawing);
            return(newDrawing);
        }
예제 #5
0
 public void Rasterize(Bitmap img, Rectangle dest, RawDrawing drawing, float penSizePerc, bool extraMargin, bool drawPoints)
 {
     using (var g = Graphics.FromImage(img)) {
         g.Clear(Color.White);
         g.SetClip(new Rectangle(0, 0, img.Width, img.Height));
         rasterize(g, drawing, penSizePerc, extraMargin, drawPoints);
     }
 }
예제 #6
0
        /// <summary>
        /// Centers and expands the drawing to [0, 1] rectanlge.
        /// </summary>
        /// <param name="drawing"></param>
        public void NormalizeInPlace(RawDrawing drawing)
        {
            float minX = float.PositiveInfinity,
                  minY = float.PositiveInfinity,
                  maxX = float.NegativeInfinity,
                  maxY = float.NegativeInfinity;

            foreach (var line in drawing.Lines)
            {
                foreach (var rawPoint in line)
                {
                    minX = Math.Min(minX, rawPoint.X);
                    minY = Math.Min(minY, rawPoint.Y);
                    maxX = Math.Max(maxX, rawPoint.X);
                    maxY = Math.Max(maxY, rawPoint.Y);
                }
            }

            if (float.IsInfinity(minX) || float.IsInfinity(minY) || float.IsInfinity(maxX) || float.IsInfinity(maxY))
            {
                // No points. Nothing to normalize.
                return;
            }

            float wid   = maxX - minX;
            float hei   = maxY - minY;
            float scale = Math.Max(wid, hei);

            if (scale < 1e-6)
            {
                // Single point or way too small. Ignore.
                return;
            }

            float xOffset = (1 - wid / scale) / 2;
            float yOffset = (1 - hei / scale) / 2;

            Contract.Assert(xOffset == 0 || yOffset == 0);

            foreach (var line in drawing.Lines)
            {
                for (int i = 0; i < line.Length; ++i)
                {
                    line[i].X = xOffset + (line[i].X - minX) / scale;
                    line[i].Y = yOffset + (line[i].Y - minY) / scale;
                }
            }
        }
예제 #7
0
        public static RawDrawing Deserialize(byte[] data)
        {
            int dataIndex     = 0;
            var resultDrawing = new RawDrawing();

            int linesCount = SerializationHelper.DeserializeInt(data, ref dataIndex);

            resultDrawing.Lines = new RawPoint[linesCount][];

            for (int l = 0; l < linesCount; ++l)
            {
                int lineLength = SerializationHelper.DeserializeInt(data, ref dataIndex);
                resultDrawing.Lines[l] = new RawPoint[lineLength];
                SerializationHelper.DeserializeArray(resultDrawing.Lines[l], data, ref dataIndex);
            }

            return(resultDrawing);
        }
예제 #8
0
 public RawDrawing(RawDrawing rd)
 {
     Lines = rd.Lines.Select(l => l.ToArray()).ToArray();
 }
예제 #9
0
 public void Rasterize(Bitmap img, RawDrawing drawing)
 {
     Rasterize(img, new Rectangle(0, 0, img.Width, img.Height), drawing, PenSizePerc, ExtraMargin, DrawPoints);
 }
예제 #10
0
 public Bitmap Rasterize(RawDrawing drawing)
 {
     return(Rasterize(drawing, ImageSize, PenSizePerc, ExtraMargin, DrawPoints));
 }
예제 #11
0
        private void rasterize(Graphics g, RawDrawing drawing, float penSizePerc, bool extraMargin, bool drawPoints)
        {
            float penSize = ((g.ClipBounds.Width + g.ClipBounds.Height) / 2) * penSizePerc;
            // Pen has to be local otherwise it cannot be user in multiple threads.
            var pen = new Pen(Color.Black, penSize)
            {
                StartCap = LineCap.Round,
                EndCap   = LineCap.Round,
                LineJoin = LineJoin.Round,
            };


            // Given points are from 0 to 1 inclusive, max is thus (size - 1).
            SizeF  drawingMult = new SizeF(g.ClipBounds.Width - 1, g.ClipBounds.Height - 1);
            PointF offset      = g.ClipBounds.Location;

            if (extraMargin)
            {
                // Make sure to fill all available space (pixel precise).
                // All strokes should be exactly to the edge of image.
                drawingMult.Width  += 2;
                drawingMult.Height += 2;

                float off = (float)Math.Ceiling(penSize / 2);
                drawingMult.Width  -= 2 * off;
                drawingMult.Height -= 2 * off;
                off -= 1;

                offset.X += off;
                offset.Y += off;
            }

            var pointsColors = new Pen[] { Pens.Red, Pens.Lime, Pens.Yellow };

            g.SmoothingMode = SmoothingMode.HighQuality;

            foreach (var line in drawing.Lines)
            {
                if (line.Length == 0)
                {
                    continue;
                }

                var pts = new PointF[line.Length];

                for (int i = 0; i < line.Length; i++)
                {
                    pts[i].X = offset.X + line[i].X * drawingMult.Width;
                    pts[i].Y = offset.Y + line[i].Y * drawingMult.Height;
                }
                g.DrawLines(pen, pts);
            }

            if (drawPoints)
            {
                int lineIndex = 0;
                foreach (var line in drawing.Lines)
                {
                    if (line.Length == 0)
                    {
                        continue;
                    }

                    var ptPen = pointsColors[lineIndex % pointsColors.Length];
                    for (int i = 0; i < line.Length; i++)
                    {
                        float x = (float)Math.Round(offset.X + line[i].X * drawingMult.Width);
                        float y = (float)Math.Round(offset.Y + line[i].Y * drawingMult.Height);
                        g.DrawLine(ptPen, x, y, x + 0.2f, y);
                        g.DrawLine(ptPen, x, y, x - 0.2f, y);
                    }

                    lineIndex += 1;
                }
            }
        }
예제 #12
0
 /// <summary>
 /// Removes lines with less than two points.
 /// </summary>
 public void CleanData(RawDrawing drawing)
 {
     drawing.Lines = drawing.Lines
                     .Where(l => l.Length >= 2)
                     .ToArray();
 }