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); }
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; }
/// <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); } }
} //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)); } }
/// <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)); }
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); }
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(); }
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); }
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); } }
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); } }
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; } }
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); }
} //获取点被反向旋转后的坐标 //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); }
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); }
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(); } } }
/// <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); }
/// <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))); }
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; } } } }
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"); }
/// <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; * }*/ }
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); }
/// <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; }
/// <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); } } }
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); }
protected override Point GetScreenPosition(PointF position) => position.Add(BoardComp.TILE_SIZE / 2).ToPoint();
public static PointF Add(this PointF inputPoint, PointF point) { return(inputPoint.Add(point.X, point.Y)); }