创建另一个具有不同坐标的图形?
Creating another Graphics with different coordinates?
是否可以使用不同的坐标系从现有 Graphics
中创建另一个 Graphics
?例如,假设黑色矩形是我在 OnPaint()
中得到的 Graphics
对象的 ClipRectangle
。如果我只想在蓝色矩形内部绘制,我将不得不不断计算偏移量。也就是说,要在蓝色矩形中的逻辑点 (0,0) 处绘制,我必须添加 x 和 y 偏移量。这使得绘图代码变得复杂。
有没有一种方法可以使用上面的 Graphics
但使用不同的坐标系来创建某种虚拟 Graphics
?如下所示
//not actual code
var virtualG = Graphics.FromExistingGraphics(e.Graphics, 200/*x1*/, 200/*y1*/, 1000/*x2*/, 600/*y2*/);
//Doing the same thing as e.Graphics.DrawLine(pen, 200, 200, 400, 400)
virtualG.DrawLine(pen, 0, 0, 200, 200);
//Draws nothing, NOT the same as e.Graphics.DrawLine(pen, 1100, 200, 1200, 400)
//, because its outside of the virtualG's bounds.
virtualG.DrawLine(pen, 900, 0, 1000, 200);
我考虑过使用位图创建一个新的 Graphics
,在那里绘制,然后将位图从 OnPaint
复制到 Graphics
的指定位置,但这可能会很慢。
如果您不想进行任何缩放,而只想将原点移动到 (200, 200),则使用 TranslateTransform as suggested previously. If you want to clip any drawings outside that rectangle, then use SetClip。
这是一个示例,显示了在平移和剪裁之前和之后绘制的同一组线条。黑线在之前,蓝线在之后(第二条蓝线被剪掉了,因此不可见)。红色矩形表示裁剪区域:
代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class Line
{
public Point ptA;
public Point ptB;
public void Draw(Graphics G, Color color)
{
using (Pen P = new Pen(color))
{
G.DrawLine(P, ptA, ptB);
}
}
}
private List<Line> Lines = new List<Line>();
private void Form1_Load(object sender, EventArgs e)
{
Lines.Add(new Line() { ptA = new Point(0,0), ptB = new Point(200, 200)});
Lines.Add(new Line() { ptA = new Point(900, 0), ptB = new Point(1000, 200) });
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics G = e.Graphics;
G.Clear(Color.DarkGray);
foreach(Line line in Lines)
{
line.Draw(G, Color.Black);
}
Rectangle rc = new Rectangle(new Point(200, 200), new Size(800, 400));
G.DrawRectangle(Pens.Red, rc);
G.SetClip(rc);
G.TranslateTransform(rc.Left, rc.Top); // origin is now at (200, 200)
foreach (Line line in Lines)
{
line.Draw(G, Color.Blue);
}
}
}
是否可以使用不同的坐标系从现有 Graphics
中创建另一个 Graphics
?例如,假设黑色矩形是我在 OnPaint()
中得到的 Graphics
对象的 ClipRectangle
。如果我只想在蓝色矩形内部绘制,我将不得不不断计算偏移量。也就是说,要在蓝色矩形中的逻辑点 (0,0) 处绘制,我必须添加 x 和 y 偏移量。这使得绘图代码变得复杂。
有没有一种方法可以使用上面的 Graphics
但使用不同的坐标系来创建某种虚拟 Graphics
?如下所示
//not actual code
var virtualG = Graphics.FromExistingGraphics(e.Graphics, 200/*x1*/, 200/*y1*/, 1000/*x2*/, 600/*y2*/);
//Doing the same thing as e.Graphics.DrawLine(pen, 200, 200, 400, 400)
virtualG.DrawLine(pen, 0, 0, 200, 200);
//Draws nothing, NOT the same as e.Graphics.DrawLine(pen, 1100, 200, 1200, 400)
//, because its outside of the virtualG's bounds.
virtualG.DrawLine(pen, 900, 0, 1000, 200);
我考虑过使用位图创建一个新的 Graphics
,在那里绘制,然后将位图从 OnPaint
复制到 Graphics
的指定位置,但这可能会很慢。
如果您不想进行任何缩放,而只想将原点移动到 (200, 200),则使用 TranslateTransform as suggested previously. If you want to clip any drawings outside that rectangle, then use SetClip。
这是一个示例,显示了在平移和剪裁之前和之后绘制的同一组线条。黑线在之前,蓝线在之后(第二条蓝线被剪掉了,因此不可见)。红色矩形表示裁剪区域:
代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class Line
{
public Point ptA;
public Point ptB;
public void Draw(Graphics G, Color color)
{
using (Pen P = new Pen(color))
{
G.DrawLine(P, ptA, ptB);
}
}
}
private List<Line> Lines = new List<Line>();
private void Form1_Load(object sender, EventArgs e)
{
Lines.Add(new Line() { ptA = new Point(0,0), ptB = new Point(200, 200)});
Lines.Add(new Line() { ptA = new Point(900, 0), ptB = new Point(1000, 200) });
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics G = e.Graphics;
G.Clear(Color.DarkGray);
foreach(Line line in Lines)
{
line.Draw(G, Color.Black);
}
Rectangle rc = new Rectangle(new Point(200, 200), new Size(800, 400));
G.DrawRectangle(Pens.Red, rc);
G.SetClip(rc);
G.TranslateTransform(rc.Left, rc.Top); // origin is now at (200, 200)
foreach (Line line in Lines)
{
line.Draw(G, Color.Blue);
}
}
}