示例#1
0
        internal static Bitmap Visualize(IReadOnlyCollection <RectangleF> rectangles)
        {
            var(bitmapSize, offsetFromCenter) = GetNecessarySizeForBitmapAndOffset(rectangles);
            var center = new PointF((float)bitmapSize.Width / 2, (float)bitmapSize.Height / 2);
            var offsetForRectangles = center.Add(offsetFromCenter);

            var canvas           = new Bitmap(bitmapSize.Width, bitmapSize.Height);
            var penForRectangles = new Pen(Color.Blue, 1);
            var resRectangles    = rectangles
                                   .Select(r => new RectangleF(r.Location.Add(offsetForRectangles), r.Size))
                                   .ToArray();

            using (var graphics = Graphics.FromImage(canvas))
            {
                graphics.Clear(Color.Black);
                graphics.DrawRectangles(penForRectangles, resRectangles);
            }

            return(canvas);
        }
示例#2
0
        private static void SetRegion(ref RectangleFSerializable rectangle, PointF?topLeft, PointF?bottomRight)
        {
            PointF topLeftValue     = topLeft ?? rectangle.Location;
            PointF bottomRightValue = bottomRight ?? PointF.Add(rectangle.Location, rectangle.Size);

            if (topLeftValue.X > bottomRightValue.X)
            {
                bottomRightValue.X = topLeftValue.X;
            }
            if (topLeftValue.Y > bottomRightValue.Y)
            {
                bottomRightValue.Y = topLeftValue.Y;
            }

            rectangle.X = topLeftValue.X;
            rectangle.Y = topLeftValue.Y;

            rectangle.Width  = bottomRightValue.X - topLeftValue.X;
            rectangle.Height = bottomRightValue.Y - topLeftValue.Y;
        }
示例#3
0
        /// <summary>
        /// Function to render the symbol
        /// </summary>
        /// <param name="map">The map</param>
        /// <param name="point">The point to symbolize</param>
        /// <param name="g">The graphics object</param>
        protected void RenderPoint(MapViewport map, Coordinate point, Graphics g)
        {
            if (point == null)
            {
                return;
            }

            PointF pp = map.WorldToImage(point);

            if (Rotation != 0f && !Single.IsNaN(Rotation))
            {
                SizeF  offset         = GetOffset();
                PointF rotationCenter = pp;

                using (var origTrans = g.Transform.Clone())
                    using (var t = g.Transform)
                    {
                        t.RotateAt(Rotation, rotationCenter);
                        t.Translate(offset.Width + 1, offset.Height + 1);
                        g.Transform = t;

                        OnRenderInternal(pp, g);

                        g.Transform = origTrans;
                    }

                using (var symTrans = new Matrix())
                {
                    symTrans.RotateAt(Rotation, rotationCenter);
                    symTrans.Translate(offset.Width + 1, offset.Height + 1);
                    var pts = CanvasArea.ToPointArray();
                    symTrans.TransformPoints(pts);
                    CanvasArea = pts.ToRectangleF();
                }
            }
            else
            {
                pp = PointF.Add(pp, GetOffset());
                OnRenderInternal(pp, g);
            }
        }
示例#4
0
        } //draws the complete actor

        private void DrawName(Graphics g, Point p1, string naam)
        {
            p1.Y = p1.Y + 40;
            p1.X = p1.X - 20;
            Size grootte = new Size(10, 10);

            grootte.Height = 5;
            grootte.Width  = 5;
            FontFamily family = new FontFamily("Arial");
            Font       font   = new Font(family, 10);

            if (naam != "")
            {
                g.DrawString(naam, font, Brushes.Black, PointF.Add(p1, grootte));
            }
            else
            {
                this.Naam = "Actor";
                g.DrawString(Naam, font, Brushes.Black, PointF.Add(p1, grootte));
            }
        }
示例#5
0
 /// <summary>
 /// Обработка перемещения указателя
 /// </summary>
 /// <param name="location"></param>
 /// <param name="modifierKeys"></param>
 public override void MouseMove(Point location, Keys modifierKeys)
 {
     base.MouseMove(location, modifierKeys);
     if (!mouseDowned)
     {
         return;
     }
     // нет выделенного маркера, значит, тянут за фигуру
     if (currentMarker != null)
     {
         // передаём положение перемещаемого маркера маркеру с исходномым номером
         markers[currentMarker.Index].Location = new PointF(currentMarker.Location.X, currentMarker.Location.Y);
         return;
     }
     if (OffsetLocation.IsEmpty)
     {
         return;
     }
     // корректируем положение всех маркеров на величину смещения
     markers.ForEach(x => x.Location = PointF.Add(x.Location, OffsetLocation));
 }
示例#6
0
        private static string DrawChar(char c, int[] hFont, PointF origin, int Angle, float Scale)
        {
            // Each vector needs to be (a) rotate to the angle of the line of text and (b) Scaled
            // One unit vector = 1 second or 90-100 feet.  Use the Scale function to adjust.
            string result = string.Empty; float X; float Y;
            bool   isFirst = true; string cr = Environment.NewLine;
            int    angle = (int)InfoSection.MagneticVariation + Angle;
            float  scale = Scale / 3600F;
            PointF end; PointF start = PointF.Empty;

            // Rotate through vectors in usual manner
            for (int i = 2; i < hFont.Length; i += 2)
            {
                Y = hFont[i + 1]; X = hFont[i];                     // X-Lon, Y-Lat
                if ((X == -1) || (Y == -1))                         // Next point is a break
                {
                    end = PointF.Empty;
                }
                else                                                // Get next vector (which will get moved to Start)
                {
                    SizeF vector = new SizeF(X * scale, Y * scale);
                    end = PointF.Add(origin, vector);
                    end = LatLongCalc.RotatePoint(end, origin, angle);
                }
                if (!(start.IsEmpty) && !(end.IsEmpty))
                {
                    result +=
                        SCTstrings.CharOut(Conversions.DecDeg2SCT(start.Y, true), Conversions.DecDeg2SCT(start.X, false),
                                           Conversions.DecDeg2SCT(end.Y, true), Conversions.DecDeg2SCT(end.X, false));
                    if (isFirst)
                    {
                        result += ";" + c.ToString();
                        isFirst = false;
                    }
                    result += cr;
                }
                start = end;                            // No matter what happened, move End to Start
            }
            return(result);                             // Lat Long string to draw ONE character!  (Sheesh)
        }
        private PointF CalculateDotLocation(int dotIndex, ref bool shouldPaintDot)
        {
            int dotAnglePosition = this.dotAnglePositions[dotIndex];

            if (dotAnglePosition < 0 || dotAnglePosition > this.DotSweepAngleLifeCycle)
            {
                shouldPaintDot = false;
                return((PointF)Point.Empty);
            }
            int    rotatedAngle = this.GetRotatedAngle(this.dotAnglePositions[dotIndex]);
            double num          = (double)rotatedAngle * Math.PI / 180.0;
            PointF pt           = new PointF((float)this.Radius * (float)Math.Cos(num), (float)(-1 * this.Radius) * (float)Math.Sin(num));

            pt    = PointF.Add(pt, new Size(this.GetRectangleCenter(this.BoundingRectangle)));
            pt.X -= (float)this.DotRadius / 2f;
            pt.Y -= (float)this.DotRadius / 2f;
            if (dotIndex == 0)
            {
                this.CurrentLeadingElementAngle = rotatedAngle;
            }
            return(pt);
        }
示例#8
0
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            base.OnMouseWheel(e);

            var oldZoomValue = m_Zoom;

            if (e.Delta > 0)
            {
                // Zoom in
                m_Zoom    *= 1 + k_ZoomIntensity;
                m_ImagePos = m_ImagePos.Sub(GetImagePositionDeltaFromScroll(e.Location, k_ZoomIntensity));
            }
            else
            {
                // Zoom out
                m_Zoom *= 1 / (1 + k_ZoomIntensity);           // m_Zoom /= 1 + k_ZoomIntensity, or basically opposite of zooming in
                var zoomDelta = 1 - 1 / (1 + k_ZoomIntensity); // percentage of how smaller the image should become
                m_ImagePos = m_ImagePos.Add(GetImagePositionDeltaFromScroll(e.Location, zoomDelta));
            }

            Invalidate();
        }
示例#9
0
        public Game()
        {
            InitializeComponent();

            ScreenBounds = ClientRectangle;

            new Player(new RectangleF((ScreenBounds.Width / 2) - 5, ScreenBounds.Height * 0.9f, 10, 10), Textures.Ship);

            float insetTop = 10, insetBottom = ScreenBounds.Height * 0.5f;
            float insetLeft = 10, insetRight = 10;

            RectangleF enemySpawnArea = ScreenBounds;

            enemySpawnArea.Location = PointF.Add(enemySpawnArea.Location, new SizeF(insetLeft, insetTop));
            enemySpawnArea.Size    -= new SizeF(insetLeft + insetRight, insetTop + insetBottom);

            float enemyWidth  = 10;
            float enemyHeight = 10;

            int enemyRows    = 10;
            int enemyColumns = 5;

            float enemySpaceX = (enemySpawnArea.Width - enemyWidth) / (enemyRows - 1);
            float enemySpaceY = (enemySpawnArea.Height - enemyHeight) / (enemyColumns - 1);

            for (int x = 0; x < enemyRows; x++)
            {
                for (int y = 0; y < enemyColumns; y++)
                {
                    new Enemy(new RectangleF(enemySpawnArea.X + x * enemySpaceX, enemySpawnArea.Y + y * enemySpaceY, 10, 10));
                }
            }

            UpdateTimer.Start();
            RedrawTimer.Start();

            this.KeyDown += new KeyEventHandler(Input.KeyDown);
            this.KeyUp   += new KeyEventHandler(Input.KeyUp);
        }
示例#10
0
        public static PointF?GetIntersection(PointF a1, PointF a2, PointF b1, PointF b2)
        {
            PointF a = GetVectorAB(a1, a2), b = GetVectorAB(b1, b2), s = GetVectorAB(a1, b1);
            float  c1 = Cross(a, b);
            float  c2 = Cross(s, b);
            float  c4 = Cross(s, a);   // c4方向顛倒

            if (c1 < 0)
            {
                c1 = -c1;
                c2 = -c2;
                c4 = -c4;
            }
            if (c1 != 0 && c2 >= 0 && c2 <= c1 && c4 >= 0 && c4 <= c1)
            {
                return(a1.Add(a.Multi(((float)((decimal)c2 / (decimal)c1)))));
            }
            else
            {
                return(null);
            }
        }
示例#11
0
        public void Update(float dt)
        {
            //сила тяжести
            var a = new PointF(0, -g);

            Velocity = Velocity.Add(a, dt);

            //трение об воздух
            Velocity = Velocity.Mult(airFriction);

            //отскок от земли
            if (Position.Y - Size.Height / 2 < 0)
            {
                Velocity = Velocity.Mult(-groundFriction);
                Position = new PointF(Position.X, Image.Height / 2);
            }
            else
            {
                //движение
                Position = Position.Add(Velocity, dt);
            }
        }
示例#12
0
        private void Control(ControlToken token, ref int i)
        {
            switch (token.Operate)
            {
                case '\\':
                    this.updated = true;
                    SizeF charSize = this.renderer.DrawChars("\\", this.charPosition);
                    charSize.Height = 0.0f;
                    this.charPosition = PointF.Add(this.charPosition, charSize);
                    break;

                case 'c':
                    if (this.renderer.Options.Brushes.Length <= token.Parameter)
                        Trace.TraceWarning("Out of brush index: {0}", token.Parameter);
                    else
                        this.renderer.BrushIndex = token.Parameter;

                    break;

                default:
                    break;
            }
        }
示例#13
0
        public override VerbResult Float(EditableView.ClickPosition position)
        {
            // let the base class take care of positioning the first line
            if (m_DefinedVertices < 2)
            {
                return(base.Float(position));
            }
            // need to calculate the coordinates of the fourth point.  We can add the 1>2 vector onto point 0
            Debug.Assert(Vertices.Count == 4);
            PointF pt = position.Snapped;

            if (pt.Equals(Vertices[2]))
            {
                return(VerbResult.Unchanged);
            }
            Vertices[2] = pt;
            SizeF szVector = Vertices[1].VectorTo(Vertices[2]);

            Vertices[3]  = PointF.Add(Vertices[0], szVector);
            m_Bounds     = CalculateBounds();
            m_Acceptable = !VerticesFormLine(0);
            DiscardPath();
            return(VerbResult.Continuing);
        }
示例#14
0
文件: BaseUnit.cs 项目: tomyqg/SemiGC
        }                                       //获取点被反向旋转后的坐标

        //virtual void OnMoveFocus( CFocus Focus,System.Drawing.SizeF Offset) = 0 ;
        public virtual RectangleF GetPointsRect()
        {
            RectangleF rect = new RectangleF();

            if (Points.Count > 0)
            {
                PointF MinP = (PointF)Points[0];
                PointF MaxP = (PointF)Points[0];
                foreach (PointF P in Points)
                {
                    MinP.X = Math.Min(P.X, MinP.X);
                    MinP.Y = Math.Min(P.Y, MinP.Y);
                    MaxP.X = Math.Max(P.X, MaxP.X);
                    MaxP.Y = Math.Max(P.Y, MaxP.Y);
                }
                rect.Location = MinP;
                rect.Size     = new SizeF(MaxP.X - MinP.X, MaxP.Y - MinP.Y);
            }
            if (this.Parent != null)
            {
                rect.Location = PointF.Add(rect.Location, this.Parent.m_RotatePosition);
            }
            return(rect);
        }
示例#15
0
        private Vector3D[] CalculateFaceVertices(Point mapLocation, Size tileSize, int mapTileHeight, SizeF offset, float pos_z)
        {
            // Location on map is complicated by tiles that are 'higher' than the tile size given for the overall map
            mapLocation.Offset(0, -tileSize.Height + mapTileHeight);

            PointF pt0 = mapLocation;
            PointF pt1 = PointF.Add(mapLocation, new Size(tileSize.Width, 0));
            PointF pt2 = PointF.Add(mapLocation, tileSize);
            PointF pt3 = PointF.Add(mapLocation, new Size(0, tileSize.Height));

            // Apply the tile offset
            pt0 = PointF.Add(pt0, offset);
            pt1 = PointF.Add(pt1, offset);
            pt2 = PointF.Add(pt2, offset);
            pt3 = PointF.Add(pt3, offset);

            // We need to use ccw winding for Wavefront objects
            Vector3D[] vertices = new Vector3D[4];
            vertices[3] = PointFToObjVertex(pt0, pos_z);
            vertices[2] = PointFToObjVertex(pt1, pos_z);
            vertices[1] = PointFToObjVertex(pt2, pos_z);
            vertices[0] = PointFToObjVertex(pt3, pos_z);
            return(vertices);
        }
示例#16
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (!base.Enabled)
            {
                return;
            }
            if (down)
            {
                var dx = e.Location.X - fixRuler.X;
                var dy = e.Location.Y - fixRuler.Y;

                var test = new PointF(ruler.X + dx, ruler.Y + dy);
                using (var path = GetAreaPath())
                    if (path.IsVisible(test) || path.IsOutlineVisible(test, Pens.Black))
                    {
                        ruler = PointF.Add(ruler, new SizeF(dx, dy));
                        UpdateData();
                        OnChangeProperties();
                        fixRuler = e.Location;
                        Invalidate();
                    }
            }
        }
示例#17
0
        /// <summary>
        /// Function that does the actual rendering
        /// </summary>
        /// <param name="pt">The point</param>
        /// <param name="g">The graphics object</param>
        protected override void OnRenderInternal(PointF pt, Graphics g)
        {
            var f = new SizeF(pt);

            foreach (var pathDefinition in _paths)
            {
                var ppts    = pathDefinition.Path.PathPoints;
                var pptsnew = new PointF[pathDefinition.Path.PointCount];
                for (int i = 0; i < pptsnew.Length; i++)
                {
                    pptsnew[i] = PointF.Add(ppts[i], f);
                }

                GraphicsPath ptmp = new GraphicsPath(pptsnew, pathDefinition.Path.PathTypes, pathDefinition.Path.FillMode);
                if (pathDefinition.Fill != null)
                {
                    g.FillPath(pathDefinition.Fill, ptmp);
                }
                if (pathDefinition.Line != null)
                {
                    g.DrawPath(pathDefinition.Line, ptmp);
                }
            }
        }
        void HandleScroll(NSTimer timer)
        {
            if (scrollingDirection == ScrollingDirection.Unknown)
            {
                return;
            }

            SizeF  frameSize     = this.CollectionView.Bounds.Size;
            SizeF  contentSize   = this.CollectionView.ContentSize;
            PointF contentOffset = this.CollectionView.ContentOffset;
            float  distance      = this.ScrollingSpeed / 60.0f;
            PointF translation   = new PointF(0, 0);

            switch (scrollingDirection)
            {
            case ScrollingDirection.Up:

            {
                distance = -distance;
                if ((contentOffset.Y + distance) <= 0.0f)
                {
                    distance = -contentOffset.Y;
                }

                translation = new PointF(0.0f, distance);
            }
            break;

            case ScrollingDirection.Down:

            {
                float maxY = Math.Max(contentSize.Height, frameSize.Height) - frameSize.Height;
                if ((contentOffset.Y + distance) >= maxY)
                {
                    distance = maxY - contentOffset.Y;
                }

                translation = new PointF(0.0f, distance);
            }
            break;

            case ScrollingDirection.Left:

            {
                distance = -distance;
                if ((contentOffset.X + distance) <= 0.0f)
                {
                    distance = -contentOffset.X;
                }

                translation = new PointF(distance, 0.0f);
            }
            break;

            case ScrollingDirection.Right:

            {
                float maxX = Math.Max(contentSize.Width, frameSize.Width) - frameSize.Width;
                if ((contentOffset.X + distance) >= maxX)
                {
                    distance = maxX - contentOffset.X;
                }

                translation = new PointF(distance, 0.0f);
            }
            break;

            default:
                break;
            }

            mockCenter      = mockCenter.Add(translation);
            mockCell.Center = mockCenter.Add(fingerTranslation);
            this.CollectionView.ContentOffset = contentOffset.Add(translation);
            NSIndexPath indexPath = this.IndexPathForItemClosestToPoint(mockCell.Center);

            this.WarpToIndexPath(indexPath);
        }
示例#19
0
        /// <summary>
        /// 绘制文字
        /// </summary>
        /// <param name="S"></param>
        /// <param name="FontSize"></param>
        /// <param name="B"></param>
        void DrawText(String S, int FontSize, Brush B)
        {
            SizeF SF = TextRenderer.MeasureText(S, new Font("宋体", FontSize));

            DrawText(S, FontSize, B, PointF.Add(CENTER_POINT, new SizeF(-SF.Width / 2, -SF.Height / 2)));
        }
示例#20
0
        private Image GenerateThumbnail()
        {
            if (_Points == null)
            {
                throw new Exception("You must provide a gesture before trying to generate a thumbnail");
            }

            if (_DrawingPen == null)
            {
                throw new Exception("You must provide a drawing pen before trying to generate a thumbnail");
            }

            // Create a bitmap object so we can draw gesture
            Bitmap bmpOutput = new Bitmap(_Size.Width, _Size.Height);

            if (_Points.Count() < 2)
            {
                return(bmpOutput);
            }

            // Create new size object accounting for pen width
            Size szeAdjusted = new Size((int)Math.Floor(_Size.Width - _DrawingPen.Width - 1), (int)Math.Floor(_Size.Height - _DrawingPen.Width - 1));

            // Create graphics object from bitmap so we can manipulate it
            _Graphics = Graphics.FromImage((Image)bmpOutput);

            // Antialias line
            _Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            PointF[] _ScaledPoints = ScaleGesture(_Points, szeAdjusted.Width - 10, szeAdjusted.Height - 10);

            // Create variable to hold last point drawn
            PointF lastPoint = _ScaledPoints.First();

            // Define size that will mark the offset to center the gesture
            int  iLeftOffset = (int)Math.Floor((double)((_Size.Width / 2) - (_ScaledSize.Width / 2)));
            int  iTopOffset  = (int)Math.Floor((double)((_Size.Height / 2) - (_ScaledSize.Height / 2)));
            Size sizOffset   = new Size(iLeftOffset, iTopOffset);

            for (int i = 0; i < _ScaledPoints.Count(); i++)
            {
                if (_WithArrow)
                {
                    if (i < _ScaledPoints.Count() - 5)
                    {
                        _Graphics.DrawLine(_DrawingPen, PointF.Add(lastPoint, sizOffset), PointF.Add(_ScaledPoints[i], sizOffset));
                    }
                    else
                    {
                        // Draw arrow on the end of the gesture
                        _Graphics.DrawLine(_ArrowPen, PointF.Add(lastPoint, sizOffset), PointF.Add(_ScaledPoints.Last(), sizOffset));

                        break;
                    }
                }
                else
                {
                    _Graphics.DrawLine(_DrawingPen, PointF.Add(lastPoint, sizOffset), PointF.Add(_ScaledPoints[i], sizOffset));
                }

                lastPoint = _ScaledPoints[i];
            }

            return((Image)bmpOutput);
        }
        void HandlePanGesture(UIPanGestureRecognizer sender)
        {
            if (sender.State == UIGestureRecognizerState.Changed)
            {
                fingerTranslation = sender.TranslationInView(this.CollectionView);
                if (_hasShouldAlterTranslationDelegateMethod)
                {
                    ((UICollectionViewDataSourceDraggable)this.CollectionView.DataSource).CollectionViewAlterTranslation(this.CollectionView, fingerTranslation);
                }

                IUICollectionViewLayoutWarpable /*UICollectionViewLayout*/ /*<UICollectionViewLayout_Warpable>*/ layout = (IUICollectionViewLayoutWarpable /*UICollectionViewLayout*/ /*<UICollectionViewLayout_Warpable>*/)this.CollectionView.CollectionViewLayout;
//				if (layout.RespondsToSelector(new Selector ("dragDirection")))
                {
                    UICollectionViewScrollDirection direction = (UICollectionViewScrollDirection)layout.DragDirection();
                    if (direction == UICollectionViewScrollDirection.Horizontal)
                    {
                        fingerTranslation.Y = 0;
                    }
                    else if (direction == UICollectionViewScrollDirection.Vertical)
                    {
                        fingerTranslation.X = 0;
                    }
                }

                mockCell.Center = mockCenter.Add(fingerTranslation);
                if (canScroll)
                {
                    IUICollectionViewLayoutWarpable /*UICollectionViewLayout*/ /*<UICollectionViewLayout_Warpable>*/ scrollLayout = (IUICollectionViewLayoutWarpable /*UICollectionViewLayout*/ /*<UICollectionViewLayout_Warpable>*/)this.CollectionView.CollectionViewLayout;

                    if (scrollLayout.ScrollDirection() == UICollectionViewScrollDirection.Vertical)
                    {
                        if (mockCell.Center.Y < (this.CollectionView.Bounds.GetMinY() + this.ScrollingEdgeInsets.Top))
                        {
                            this.SetupScrollTimerInDirection(ScrollingDirection.Up);
                        }
                        else
                        {
                            if (mockCell.Center.Y > (this.CollectionView.Bounds.GetMaxY() - this.ScrollingEdgeInsets.Bottom))
                            {
                                this.SetupScrollTimerInDirection(ScrollingDirection.Down);
                            }
                            else
                            {
                                this.InvalidatesScrollTimer();
                            }
                        }
                    }
                    else
                    {
                        if (mockCell.Center.X < (this.CollectionView.Bounds.GetMinX() + this.ScrollingEdgeInsets.Left))
                        {
                            this.SetupScrollTimerInDirection(ScrollingDirection.Left);
                        }
                        else
                        {
                            if (mockCell.Center.X > (this.CollectionView.Bounds.GetMaxX() - this.ScrollingEdgeInsets.Right))
                            {
                                this.SetupScrollTimerInDirection(ScrollingDirection.Right);
                            }
                            else
                            {
                                this.InvalidatesScrollTimer();
                            }
                        }
                    }
                }

                if (scrollingDirection > ScrollingDirection.Unknown)
                {
                    return;
                }

                PointF      point     = sender.LocationInView(this.CollectionView);
                NSIndexPath indexPath = this.IndexPathForItemClosestToPoint(point);
                this.WarpToIndexPath(indexPath);
                if (this.DropOnToDeleteView != null && this.DropOnToDeleteView.Superview != null)
                {
                    bool highlighted = this.DropOnToDeleteView.Frame.Contains(point);
                    this.DropOnToDeleteView.Highlighted = highlighted;
                    if (!highlighted)
                    {
                        PointF center   = this.DropOnToDeleteView.Center;
                        float  distance = (center.X - point.X) * (center.X - point.X) + (center.Y - point.Y) * (center.Y - point.Y);
                        this.DropOnToDeleteView.Alpha = (float)(2f - Math.Atan(distance / 10000.0f)) / 2f;
                    }
                    else
                    {
                        this.DropOnToDeleteView.Alpha = 1.0f;
                    }
                }
            }
        }
示例#22
0
 public void AddTest()
 {
     Assert.AreEqual(new PointF(3, 4), PointF.Add(new PointF(1, 1), new Size(2, 3)), "ADDTEST#1");
     Assert.AreEqual(new PointF(4, 5), PointF.Add(new PointF(2, 2), new SizeF(2, 3)), "ADDTEST#2");
 }
示例#23
0
        /// <summary>
        /// gets points for transform this image
        /// </summary>
        /// <param name="drawRect">the box where to draw image</param>
        /// <param name="imageWidth">image width</param>
        /// <param name="imageHeight">image height</param>
        /// <param name="scaleX">scale horizontal</param>
        /// <param name="scaleY">scale vertical</param>
        /// <param name="offsetX">offset of left</param>
        /// <param name="offsetY">offset of top</param>
        /// <param name="upperLeft">out start of vectors</param>
        /// <param name="upperRight">out end of frist vector</param>
        /// <param name="lowerLeft">out end of second vector</param>
        public void GetImageAngleTransform(RectangleF drawRect, float imageWidth, float imageHeight, float scaleX, float scaleY, float offsetX, float offsetY, out PointF upperLeft, out PointF upperRight, out PointF lowerLeft)
        {
            RectangleF rect = drawRect;

            switch (SizeMode)
            {
            case PictureBoxSizeMode.Normal:
            case PictureBoxSizeMode.AutoSize:
                rect.Width  = imageWidth * scaleX;
                rect.Height = imageHeight * scaleY;
                if (Angle == 90 || Angle == 180)
                {
                    rect.X -= rect.Width - drawRect.Width;
                }
                if (Angle == 180)
                {
                    rect.Y -= rect.Height - drawRect.Height;
                }
                break;

            case PictureBoxSizeMode.CenterImage:
                rect.Offset((Width - imageWidth) * scaleX / 2, (Height - imageHeight) * scaleY / 2);
                rect.Width  = imageWidth * scaleX;
                rect.Height = imageHeight * scaleY;
                break;

            case PictureBoxSizeMode.StretchImage:
                break;

            case PictureBoxSizeMode.Zoom:
                /*float kx = drawRect.Width / imageWidth;
                *  float ky = drawRect.Height / imageHeight;
                *  if (kx < ky)
                *  rect.Height = imageHeight * kx;
                *  else
                *  rect.Width = imageWidth * ky;
                *  rect.Offset(
                *  (Width * e.ScaleX - rect.Width) / 2,
                *  (Height * e.ScaleY - rect.Height) / 2);*/
                break;
            }

            float gridCompensationX = offsetX + rect.X;

            gridCompensationX = (int)gridCompensationX - gridCompensationX;
            float gridCompensationY = offsetY + rect.Y;

            gridCompensationY = (int)gridCompensationY - gridCompensationY;
            if (gridCompensationX < 0)
            {
                gridCompensationX = 1 + gridCompensationX;
            }
            if (gridCompensationY < 0)
            {
                gridCompensationY = 1 + gridCompensationY;
            }

            rect.Offset(gridCompensationX, gridCompensationY);

            upperLeft  = new PointF(0, 0);
            upperRight = new PointF(rect.Width, 0);
            lowerLeft  = new PointF(0, rect.Height);
            float angle = Angle;

            switch (SizeMode)
            {
            case PictureBoxSizeMode.Normal:
            {
                upperLeft = MovePointOnAngle(drawRect.Location, drawRect.Size, Angle);
                PointF ur = rotateVector(upperRight, angle);
                PointF ll = rotateVector(lowerLeft, angle);
                upperRight = PointF.Add(upperLeft, new SizeF(ur));
                lowerLeft  = PointF.Add(upperLeft, new SizeF(ll));
            }
            break;

            case PictureBoxSizeMode.StretchImage:
            {
                upperLeft = MovePointOnAngle(drawRect.Location, drawRect.Size, Angle);

                upperRight = MovePointOnAngle(
                    drawRect.Location,
                    drawRect.Size, Angle + 90);
                lowerLeft = MovePointOnAngle(
                    drawRect.Location,
                    drawRect.Size, Angle + 270);
            }
            break;

            case PictureBoxSizeMode.CenterImage:
            {
                PointF rotatedVector;
                float  w = rect.Left - (drawRect.Left + drawRect.Width / 2);
                float  h = rect.Top - (drawRect.Top + drawRect.Height / 2);
                rotatedVector = rotateVector(new PointF(w, h), Angle);
                upperLeft     = new PointF(rect.Left + rotatedVector.X - w, rect.Top + rotatedVector.Y - h);
                rotatedVector = rotateVector(new PointF(rect.Width, 0), Angle);
                upperRight    = new PointF(upperLeft.X + rotatedVector.X, upperLeft.Y + rotatedVector.Y);
                rotatedVector = rotateVector(new PointF(0, rect.Height), Angle);
                lowerLeft     = new PointF(upperLeft.X + rotatedVector.X, upperLeft.Y + rotatedVector.Y);
            }
            break;

            case PictureBoxSizeMode.AutoSize:
            case PictureBoxSizeMode.Zoom:
            {
                rect = new RectangleF(0, 0, imageWidth * 100f, imageHeight * 100f);
                PointF center = new PointF(drawRect.Left + drawRect.Width / 2,
                                           drawRect.Top + drawRect.Height / 2);
                PointF[] p = new PointF[4];
                p[0] = new PointF(-rect.Width / 2, -rect.Height / 2);
                p[1] = new PointF(rect.Width / 2, -rect.Height / 2);
                p[2] = new PointF(rect.Width / 2, rect.Height / 2);
                p[3] = new PointF(-rect.Width / 2, rect.Height / 2);

                float scaleToMin = 1;

                for (int i = 0; i < 4; i++)
                {
                    p[i] = rotateVector(p[i], Angle);
                }

                for (int i = 0; i < 4; i++)
                {
                    if (p[i].X * scaleToMin < -drawRect.Width / 2)
                    {
                        scaleToMin = -drawRect.Width / 2 / p[i].X;
                    }
                    if (p[i].X * scaleToMin > drawRect.Width / 2)
                    {
                        scaleToMin = drawRect.Width / 2 / p[i].X;
                    }

                    if (p[i].Y * scaleToMin < -drawRect.Height / 2)
                    {
                        scaleToMin = -drawRect.Height / 2 / p[i].Y;
                    }
                    if (p[i].Y * scaleToMin > drawRect.Height / 2)
                    {
                        scaleToMin = drawRect.Height / 2 / p[i].Y;
                    }
                }
                upperLeft  = PointF.Add(center, new SizeF(p[0].X * scaleToMin, p[0].Y * scaleToMin));
                upperRight = PointF.Add(center, new SizeF(p[1].X * scaleToMin, p[1].Y * scaleToMin));
                lowerLeft  = PointF.Add(center, new SizeF(p[3].X * scaleToMin, p[3].Y * scaleToMin));
            }
            break;
            }

            if (ImageAlign != ImageAlign.None)
            {
                UpdateAlign(drawRect, ref upperLeft, ref upperRight, ref lowerLeft);
            }

            /*switch (Angle)
             * {
             * case 90:
             *    upperLeft = new PointF(rect.Right, rect.Top);
             *    upperRight = new PointF(rect.Right, rect.Bottom);
             *    lowerLeft = new PointF(rect.Left, rect.Top);
             *    break;
             *
             * case 180:
             *    upperLeft = new PointF(rect.Right, rect.Bottom);
             *    upperRight = new PointF(rect.Left, rect.Bottom);
             *    lowerLeft = new PointF(rect.Right, rect.Top);
             *    break;
             *
             * case 270:
             *    upperLeft = new PointF(rect.Left, rect.Bottom);
             *    upperRight = new PointF(rect.Left, rect.Top);
             *    lowerLeft = new PointF(rect.Right, rect.Bottom);
             *    break;
             *
             * default:
             *    upperLeft = new PointF(rect.Left, rect.Top);
             *    upperRight = new PointF(rect.Right, rect.Top);
             *    lowerLeft = new PointF(rect.Left, rect.Bottom);
             *    break;
             * }*/
            /* default:
             *           PointF rotatedVector;
             *           float w = rect.Left - (drawRect.Left + drawRect.Width / 2) ;
             *           float h = rect.Top - (drawRect.Top + drawRect.Height/2);
             *           rotatedVector = rotateVector(new PointF(w, h), Angle);
             *           upperLeft = new PointF(rect.Left + rotatedVector.X - w, rect.Top + rotatedVector.Y - h);
             *           rotatedVector = rotateVector(new PointF(rect.Width, 0), Angle);
             *           upperRight = new PointF(upperLeft.X + rotatedVector.X, upperLeft.Y + rotatedVector.Y);
             *           rotatedVector = rotateVector(new PointF(0, rect.Height), Angle);
             *           lowerLeft = new PointF(upperLeft.X + rotatedVector.X, upperLeft.Y + rotatedVector.Y);
             *           break;
             *   }*/
        }
示例#24
0
        public Bitmap DrawMeasurement(Measurement measurement)
        {
            Graphics graph = Graphics.FromImage(Bmp);
            Pen      pen   = new Pen(Color.Yellow, 8.0F);

            pen.Color = System.Drawing.Color.Yellow;

            graph.DrawLine(pen, PointF.Add(new Point(0, 0), new Size(height / 2, width / 2)), PointF.Add(measurement.A.EndPoint, new Size(height / 2, width / 2)));
            pen.Color = System.Drawing.Color.Green;
            graph.DrawLine(pen, PointF.Add(new Point(0, 0), new Size(height / 2, width / 2)), PointF.Add(measurement.B.EndPoint, new Size(height / 2, width / 2)));
            pen.Color = System.Drawing.Color.Red;
            graph.DrawLine(pen, PointF.Add(new Point(0, 0), new Size(height / 2, width / 2)), PointF.Add(measurement.C.EndPoint, new Size(height / 2, width / 2)));
            return(Bmp);
        }
示例#25
0
        /// <summary>
        /// Arranges the tags to form the distinctive tag cloud layout.
        /// </summary>
        public void Arrange()
        {
            RectangleF totalBounds = RectangleF.Empty;
            Random     rnd         = IsDeterministic ? new Random(0) : new Random();

            _renderItems.Clear();
            CycleCount = 0;

            // sort tags by frequency (highest first)
            var orderedItems = Items.OrderByDescending(x => x.Frequency);

            int maxFrequency = orderedItems.Select(x => x.Frequency).DefaultIfEmpty(0).First();
            int minFrequency = orderedItems.Select(x => x.Frequency).DefaultIfEmpty(0).Last();

            foreach (TagItem tag in orderedItems)
            {
                RectangleF bestBounds = RectangleF.Empty;
                int        bestDist   = 0;

                // calculate font size to use
                float scale = (maxFrequency != minFrequency)
                                        ? ((float)(tag.Frequency - minFrequency) / (float)(maxFrequency - minFrequency))
                                        : 0;

                float fontSize = BASE_FONT_SIZE + (BASE_FONT_SIZE * (FontSizeGradient * scale));

                // measure text and calculate bounds
                SizeF sz;
                using (Font font = new Font(FontFamily, fontSize, FontStyle)) {
                    sz = TextRenderer.MeasureText(tag.Text, font, Size.Empty, TEXT_FORMAT_FLAGS);
                }

                SizeF      offset    = new SizeF(-(sz.Width / 2f), -(sz.Height / 2f));
                RectangleF tagBounds = new RectangleF(offset.ToPointF(), sz);

                // initialise rendering info with what we know so far
                TagRenderInfo info = new TagRenderInfo()
                {
                    Item = tag, FontSize = fontSize
                };

                // try a random subset of the angles between 0 and 360 degrees
                foreach (int angle in Enumerable.Range(0, 360).Shuffle(rnd).Take(90))
                {
                    int tagDist = 0;

                    while (true)
                    {
                        // measure outward from the origin
                        PointF p = PointF.Empty.GetRadialPoint(angle, tagDist);
                        tagBounds.Location = PointF.Add(p, offset);

                        // check whether tag would overlap (collide) with previously-placed tags
                        bool collision = false;
                        foreach (var other in _renderItems)
                        {
                            CycleCount++;

                            if (other.Bounds.IntersectsWith(tagBounds))
                            {
                                collision = true;
                                break;
                            }
                        }

                        // once there are no collisions this location becomes a candidate angle
                        if (!collision)
                        {
                            break;
                        }

                        // ...otherwise, increase distance from origin and try again
                        tagDist += 5;

                        // if we've already exceeded the most optimal distance, we can stop here
                        if ((bestDist != 0) && (tagDist > bestDist))
                        {
                            break;
                        }
                    }

                    // determine whether this candidate angle produces the most optimal solution
                    RectangleF tryBounds = RectangleF.Union(totalBounds, tagBounds);

                    float tryArea        = (tryBounds.Width * tryBounds.Height);
                    float bestArea       = (bestBounds.Width * bestBounds.Height);
                    float tryAspectDiff  = Math.Abs((tryBounds.Width / tryBounds.Height) - PreferredAspectRatio);
                    float bestAspectDiff = Math.Abs((bestBounds.Width / bestBounds.Height) - PreferredAspectRatio);

                    bool isBest = (bestBounds.IsEmpty || (tryArea < bestArea)) &&
                                  (bestBounds.IsEmpty || (tryAspectDiff < bestAspectDiff)) &&
                                  ((bestDist == 0) || (tagDist <= bestDist));

                    if (isBest)
                    {
                        // this becomes the new most optimal solution (until/if a better one is found)
                        bestBounds  = tryBounds;
                        bestDist    = tagDist;
                        info.Bounds = tagBounds;

                        // if the total bounds did not increase at all, skip over the remaining angles
                        if (bestBounds == totalBounds)
                        {
                            break;
                        }
                    }
                }

                // commit the current tag
                _renderItems.AddLast(info);
                totalBounds = bestBounds;
            }

            Bounds = totalBounds;
        }
示例#26
0
        /// <summary>
        /// Draws a space based on a position given.
        /// </summary>
        /// <param name="pen">The pen to use. This can change the color of the space drawn.</param>
        /// <param name="point">The X and Y coordinate to draw at.</param>
        /// <param name="g">Graphics instance to use.</param>
        private void DrawSpace(Pen pen, PointF point, Graphics g)
        {
            PointF point2 = PointF.Add(point, new SizeF(1, 0));

            g.DrawLine(pen, point, point2);
        }
        private void TestImage(IEnumerable <Point> arrayOfTestPoints)
        {
            if (_trace)
            {
                string imageType;
                if (_sourceImageType == ImageTypes.Mono16)
                {
                    imageType = "Mono16";
                }
                else if (_sourceImageType == ImageTypes.Mono8)
                {
                    imageType = "Mono8";
                }
                else if (_sourceImageType == ImageTypes.Mono8Signed)
                {
                    imageType = "Mono8Signed";
                }
                else if (_sourceImageType == ImageTypes.Mono16Signed)
                {
                    imageType = "Mono16Signed";
                }
                else
                {
                    imageType = "Rgb";
                }

                TraceLine("");
                TraceLine(imageType);
                TraceLine(String.Format("Scale (Fit/Scale): {0}/{1}", _scaleToFit, _scale));
                TraceLine(String.Format("Orientation(FH/FV/R): {0}/{1}/{2}", _flipHorizontal, _flipVertical, _rotation));
                TraceLine(String.Format("Translation: {0}, {1}", _translationX, _translationY));
            }

            CreateImageLayer(_sourceImageType);
            CreatePhantom();

            //render the image to a bitmap
            Bitmap dstBitmap = ImageRendererTestUtilities.RenderLayer(_image, _dstWidth, _dstHeight);

            if (_traceBitmap)
            {
                string strTraceBitmap = "Bitmap:\n";

                for (int y = 0; y < dstBitmap.Height; y++)
                {
                    for (int x = 0; x < dstBitmap.Width; x++)
                    {
                        byte pixelValue = dstBitmap.GetPixel(x, y).R;
                        strTraceBitmap += String.Format("{0}  ", (int)pixelValue);
                    }

                    strTraceBitmap += "\n";
                }

                TraceLine(strTraceBitmap);
            }

            foreach (Point dstPoint in arrayOfTestPoints)
            {
                // //The point of the unit test here is to do the same bilinear calculation as is done in the
                // //actual interpolation code, but in a more reliable & simpler way (e.g. not using pointer
                // //arithmetic, offsets, rectangles, etc).
                Rectangle  dstViewableRectangle;
                RectangleF srcViewableRectangle;
                ImageRenderer.CalculateVisibleRectangles(_image, new Rectangle(0, 0, _dstWidth, _dstHeight), out dstViewableRectangle, out srcViewableRectangle);

                byte dstValue = dstBitmap.GetPixel(dstPoint.X, dstPoint.Y).R;                 //just check the value of R.

                if (dstViewableRectangle.Contains(dstPoint))
                {
                    PointF dstTestPoint = new PointF(dstPoint.X + 0.5F, dstPoint.Y + 0.5F);
                    PointF srcTestPoint = _image.SpatialTransform.ConvertToSource(dstTestPoint);

                    float tolerance = 1 / (8F * _fixedScale);

                    // We can take advantage of the fact that we are using fixed point arithmetic to do the interpolation
                    // because it essentially means that there is a discrete set of resulting values for a given 4-pixel
                    // region (dx,dy between 0.0 -> 1.0 translates to 0/128 -> 128/128 in fixed point).
                    // Because we use the SpatialTransform class to calculate the source coordinate in the C# world,
                    // and 2 rectangles in the C++ world, we can't expect to get *exactly* the same answer in both cases.
                    // Therefore, we calculate the values at source points offset by a tolerance much smaller than 1/128,
                    // so that if by chance the source coordinates are teetering on a fixed-point boundary (e.g. slight
                    // changes would result in dx or dy being off by +-1/128) then we can still be confident that the
                    // source coordinates the interpolator is calculating are reasonable, and thus the interpolated value
                    // is correct, even if it's not exactly what we calculate in C# with zero-tolerance.
                    // The tolerance used here is 1/(8*128) ~= 0.001.  When the test passes, this means that the C# and
                    // C++ calculations of the source pixel coordinate (and thus, dx/dy and the interpolated value) agree to
                    // within one one-thousandth of a pixel.
                    List <SizeF> offsets = new List <SizeF>();
                    offsets.Add(new SizeF(0F, 0F));
                    offsets.Add(new SizeF(-tolerance, -tolerance));
                    offsets.Add(new SizeF(-tolerance, +tolerance));
                    offsets.Add(new SizeF(+tolerance, -tolerance));
                    offsets.Add(new SizeF(+tolerance, +tolerance));

                    bool success = false;
                    int  i       = 0;
                    foreach (SizeF offset in offsets)
                    {
                        PointF srcPoint00         = PointF.Add(srcTestPoint, offset);
                        byte   backCalculateValue = PerformBilinearInterpolationAt(srcPoint00);

                        if (_trace)
                        {
                            string strMessage = String.Format("Test Point #{0} ({1}, {2}): {3}, BackCalculated({4:F16}, {5:F16}): {6}\n",
                                                              ++i, dstTestPoint.X, dstTestPoint.Y, dstValue, srcPoint00.X, srcPoint00.Y,
                                                              backCalculateValue);

                            TraceLine(strMessage);
                        }

                        if (backCalculateValue == dstValue)
                        {
                            success = true;
                            break;
                        }
                    }

                    Assert.IsTrue(success, "Failed for all test points within tolerance range.");
                }
                else
                {
                    //The bilinear interpolation algorithm should not calculate any values outside the dstViewableRectangle.
                    string strMessage = String.Format("Point outside rectangle ({0}, {1}) = {2}", dstPoint.X, dstPoint.Y, dstValue);

                    if (_trace)
                    {
                        TraceLine(strMessage);
                    }

                    Assert.AreEqual(0, dstValue, strMessage);
                }
            }
        }
示例#28
0
        public static ClipperLib.PolyTree ExecuteClipper(TmxMap tmxMap, TmxLayer tmxLayer, TransformPointFunc xfFunc, ProgressFunc progFunc)
        {
            // The "fullClipper" combines the clipper results from the smaller pieces
            ClipperLib.Clipper fullClipper = new ClipperLib.Clipper();

            // From the perspective of Clipper lines are polygons too
            // Closed paths == polygons
            // Open paths == lines
            var polygonGroups = from y in Enumerable.Range(0, tmxLayer.Height)
                                from x in Enumerable.Range(0, tmxLayer.Width)
                                let rawTileId = tmxLayer.GetRawTileIdAt(x, y)
                                                let tileId = TmxMath.GetTileIdWithoutFlags(rawTileId)
                                                             where tileId != 0
                                                             let tile = tmxMap.Tiles[tileId]
                                                                        from polygon in tile.ObjectGroup.Objects
                                                                        where (polygon as TmxHasPoints) != null
                                                                        let groupX = x / LayerClipper.GroupBySize
                                                                                     let groupY = y / LayerClipper.GroupBySize
                                                                                                  group new
            {
                PositionOnMap         = tmxMap.GetMapPositionAt(x, y, tile),
                HasPointsInterface    = polygon as TmxHasPoints,
                TmxObjectInterface    = polygon,
                IsFlippedDiagnoally   = TmxMath.IsTileFlippedDiagonally(rawTileId),
                IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId),
                IsFlippedVertically   = TmxMath.IsTileFlippedVertically(rawTileId),
                TileCenter            = new PointF(tile.TileSize.Width * 0.5f, tile.TileSize.Height * 0.5f),
            }
            by Tuple.Create(groupX, groupY);

            int groupIndex = 0;
            int groupCount = polygonGroups.Count();

            foreach (var polyGroup in polygonGroups)
            {
                if (groupIndex % 5 == 0)
                {
                    progFunc(String.Format("Clipping '{0}' polygons: {1}%", tmxLayer.Name, (groupIndex / (float)groupCount) * 100));
                }
                groupIndex++;

                // The "groupClipper" clips the polygons in a smaller part of the world
                ClipperLib.Clipper groupClipper = new ClipperLib.Clipper();

                // Add all our polygons to the Clipper library so it can reduce all the polygons to a (hopefully small) number of paths
                foreach (var poly in polyGroup)
                {
                    // Create a clipper library polygon out of each and add it to our collection
                    ClipperPolygon clipperPolygon = new ClipperPolygon();

                    // Our points may be transformed due to tile flipping/rotation
                    // Before we transform them we put all the points into local space relative to the tile
                    SizeF    offset            = new SizeF(poly.TmxObjectInterface.Position);
                    PointF[] transformedPoints = poly.HasPointsInterface.Points.Select(pt => PointF.Add(pt, offset)).ToArray();

                    // Now transform the points relative to the tile
                    TmxMath.TransformPoints(transformedPoints, poly.TileCenter, poly.IsFlippedDiagnoally, poly.IsFlippedHorizontally, poly.IsFlippedVertically);

                    foreach (var pt in transformedPoints)
                    {
                        float x = poly.PositionOnMap.X + pt.X;
                        float y = poly.PositionOnMap.Y + pt.Y;

                        ClipperLib.IntPoint point = xfFunc(x, y);
                        clipperPolygon.Add(point);
                    }

                    // Because of Unity's cooridnate system, the winding order of the polygons must be reversed
                    clipperPolygon.Reverse();

                    // Add the "subject"
                    groupClipper.AddPath(clipperPolygon, ClipperLib.PolyType.ptSubject, poly.HasPointsInterface.ArePointsClosed());
                }

                // Get a solution for this group
                ClipperLib.PolyTree solution = new ClipperLib.PolyTree();
                groupClipper.Execute(ClipperLib.ClipType.ctUnion, solution, LayerClipper.SubjectFillRule, LayerClipper.ClipFillRule);

                // Combine the solutions into the full clipper
                fullClipper.AddPaths(ClipperLib.Clipper.ClosedPathsFromPolyTree(solution), ClipperLib.PolyType.ptSubject, true);
                fullClipper.AddPaths(ClipperLib.Clipper.OpenPathsFromPolyTree(solution), ClipperLib.PolyType.ptSubject, false);
            }
            progFunc(String.Format("Clipping '{0}' polygons: 100%", tmxLayer.Name));

            ClipperLib.PolyTree fullSolution = new ClipperLib.PolyTree();
            fullClipper.Execute(ClipperLib.ClipType.ctUnion, fullSolution, LayerClipper.SubjectFillRule, LayerClipper.ClipFillRule);

            return(fullSolution);
        }
示例#29
0
 protected override Point GetScreenPosition(PointF position) =>
 position.Add(BoardComp.TILE_SIZE / 2).ToPoint();
示例#30
0
 public static PointF Add(this PointF inputPoint, PointF point)
 {
     return(inputPoint.Add(point.X, point.Y));
 }