用c#裁剪矩形
Posted
技术标签:
【中文标题】用c#裁剪矩形【英文标题】:Clipping rectangle with c# 【发布时间】:2012-11-12 06:21:26 【问题描述】:我有一些代码可以生成带有随机角度的矩形:
但我需要通过父边框切割子矩形,例如
我的代码:http://pastebin.com/b6ry8j68
谁能帮我解决算法问题?
【问题讨论】:
如何确定矩形的父子关系? 【参考方案1】:使用SetClip 属性很容易做到。
基本上你需要添加这段代码:
if (!pre_defined)
g.SetClip(new Rectangle(x, y, 600, 300));
就在画线命令之前。其中 x 和 y 是父矩形的坐标。这很容易从您的功能中获得。
这是一个完整的功能:
public void drawRectangle(double Width, double Height, int A, bool pre_defined)
Graphics g = pictureBox1.CreateGraphics();
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
System.Drawing.Brush brush = new System.Drawing.SolidBrush(Color.FromArgb(r.Next(0, 251), r.Next(0, 251), r.Next(0, 251)));
Pen myPen = new Pen(brush, 2);
myPen.Width = 2;
int x = center.X;
int y = center.Y;
//top left
P[0] = new PointF((float)Math.Round(x + (Width / 2) * Math.Cos(A) + (Height / 2) * Math.Sin(A)), (float)Math.Round(y - (Height / 2) * Math.Cos(A) + (Width / 2) * Math.Sin(A)));
//top right
P[1] = new PointF((float)Math.Round(x - (Width / 2) * Math.Cos(A) + (Height / 2) * Math.Sin(A)), (float)Math.Round(y - (Height / 2) * Math.Cos(A) - (Width / 2) * Math.Sin(A)));
//bottom left
P[2] = new PointF((float)Math.Round(x + (Width / 2) * Math.Cos(A) - (Height / 2) * Math.Sin(A)), (float)Math.Round(y + (Height / 2) * Math.Cos(A) + (Width / 2) * Math.Sin(A)));
//bottom right
P[3] = new PointF((float)Math.Round(x - (Width / 2) * Math.Cos(A) - (Height / 2) * Math.Sin(A)), (float)Math.Round(y + (Height / 2) * Math.Cos(A) - (Width / 2) * Math.Sin(A)));
if (!pre_defined)
g.SetClip(new Rectangle(50, 50, 600, 300));
g.DrawLine(myPen, P[0], P[1]);
g.DrawLine(myPen, P[1], P[3]);
g.DrawLine(myPen, P[3], P[2]);
g.DrawLine(myPen, P[2], P[0]);
编辑: 这不是一个完整的示例,因为这个示例只会将 Clip 设置为父宽度和高度。您需要修改函数以提供每个元素的宽度和高度。但是现在我正在查看您提供的图片,它看起来比我想象的要复杂。 您最终可能会存储所有随机值的数组,然后按大小对其进行排序,然后绘制所有元素。
【讨论】:
是的,它确实有效,但这是大学任务,我认为我必须在没有任何像 setClip 这样的助手的情况下实现实现 这么好的答案。经常遇到这个问题。【参考方案2】:这是一个老问题,但有人可能仍需要一个简单的解决方法。
最简单的解决方案是在定义尺寸的图形表面上绘制这些矩形,这样任何超出该尺寸或其边框的绘制路径都会被自动剪裁。从已定义大小的位图创建图形对象会将任何内容限制为该大小。之后可以将位图绘制到您的屏幕图形对象上,以便直接绘制到屏幕上。
请注意,此过程也用作双缓冲技术,有助于减少直接在屏幕上绘制时的闪烁效果。
以下示例显示了如何设置大小的图形对象。
见:Information about PaintEventArgs overriding
///<summary>
/// Most common method for painting to the screen.
/// Available on all control class objects by overriding
/// the OnPaint method of the base class.
///</summary>
protected virtual new void OnPaint(PaintEventArgs e)
// We assume here that your control's screen graphics
// area is at least 500x400 to see the full results
// otherwise please resize your form or control to accommodate
// Define your parent border size
Size ParentBorder = new Size(400, 300);
// Initialize a new bitmap having a size of ParentBorder and set
// it to the screen's pixel format. Setting the bitmap to the
// screens pixel format can save many milliseconds in processing
// due to pixel size conversions otherwise required
Bitmap Bmp = new Bitmap(ParentBorder.Width, ParentBorder.Height, Graphics.FromHwnd(IntPtr.Zero));
// Next we create a graphics object tied to our bitmap for
// drawing our rectangles within a defined border
Graphics BmpGfx = Graphics.FromImage(Bmp);
//
// Draw your rectangles here! A sample is below includes painting
// to the screen to illustrate this process
//
//
// Rotate first rectangle 20 or transform as needed :)
BmpGfx.RotateTransform(20);
//
// Sample 1: This one just shows a red rectangle near the center
// of the ParentBorder graphics object
BmpGfx.DrawRectangle(new Pen(Color.Red), new Rectangle(new Point(100, -20), new Size(200, 200)));
//
// Reset back to normal transform
BmpGfx.ResetTransform();
//
// Rotate second rectangle 60
BmpGfx.RotateTransform(60);
//
// Sample 2: This one just shows a cropped blue rectangle at
// the borders
BmpGfx.DrawRectangle(new Pen(Color.Blue), new Rectangle(new Point(145, -200), new Size(300, 300)));
//
// Reset back to normal transform for drawing a nice ParentBorder
BmpGfx.ResetTransform();
//
// Border: This one just draws an Orange border around the ParaentBorder
// of the Bmp graphics object
BmpGfx.DrawRectangle(new Pen(Color.Orange), new Rectangle(Point.Empty, new Size(Bmp.Width - 1, Bmp.Height - 1)));
// Finally put your drawing to the screen. 50 points left and top so
// you can see the border and that nothing exceeds that ParaentBorder
e.Graphics.DrawImage(Bmp, new Point(50,50));
// Save your BMP to a file if you prefer or to "preserve the graphics"
// place the bmp in global scope (a global variable just don't forget
// to dispose when no longer needed)
// Please dispose of your goods as variable objects not inline like
// done above to keep the GC happy of course. The below method ensures
// resources are fully released for immediate cleanup by the GC.
Bmp.Dispose();
Bmp = null;
BmpGfx.Dispose();
BmpGfx = null;
【讨论】:
以上是关于用c#裁剪矩形的主要内容,如果未能解决你的问题,请参考以下文章