C# 创建另一个具有不同坐标的图形?

C# 创建另一个具有不同坐标的图形?,c#,winforms,gdi+,C#,Winforms,Gdi+,是否可以使用不同的坐标系创建另一个图形形成现有的图形?例如,假设黑色矩形是我在OnPaint()中得到的Graphics对象的ClipRectangle。如果我只想在蓝色矩形内绘制,我必须不断计算偏移量。也就是说,要在蓝色矩形中的逻辑点(0,0)处绘制,我必须添加x和y偏移。这使得绘图代码变得复杂 是否有一种方法可以使用上面的图形创建某种虚拟图形,但坐标系不同?像下面这样 //not actual code var virtualG = Graphics.FromExistingGraphics

是否可以使用不同的坐标系创建另一个
图形
形成现有的
图形
?例如,假设黑色矩形是我在
OnPaint()
中得到的
Graphics
对象的
ClipRectangle
。如果我只想在蓝色矩形内绘制,我必须不断计算偏移量。也就是说,要在蓝色矩形中的逻辑点(0,0)处绘制,我必须添加x和y偏移。这使得绘图代码变得复杂

是否有一种方法可以使用上面的
图形
创建某种虚拟
图形
,但坐标系不同?像下面这样

//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); 
我考虑过使用位图创建一个新的
图形
,在那里绘制,然后从
OnPaint
将位图复制到
图形
的指定位置,但这可能会很慢


如果您不想进行任何缩放,只想将原点移动到(200200),则按照前面的建议使用。如果要剪裁该矩形外的任何图形,请使用

下面是一个示例,显示了在平移和剪裁之前和之后绘制的同一组线。黑线在前面,而蓝线在后面(第二条蓝线被剪裁,因此不可见)。红色矩形显示剪切区域:

代码:

公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
}
公共班级线
{
公共点ptA;
公共点公共交通局;
公共空白绘制(图形G、颜色)
{
使用(笔P=新笔(颜色))
{
G.拉线(P、ptA、ptB);
}
}
}
私有列表行=新列表();
私有void Form1\u加载(对象发送方、事件参数e)
{
Add(newline(){ptA=newpoint(0,0),ptB=newpoint(200200)});
Add(newline(){ptA=newpoint(900,0),ptB=newpoint(1000200)});
}        
私有void pictureBox1_Paint(对象发送方,PaintEventArgs e)
{
图形G=e.图形;
G.透明(颜色为暗灰色);
foreach(行中的行)
{
线条。绘制(G,颜色。黑色);
}
矩形rc=新矩形(新点(200200),新尺寸(800400));
G.绘图矩形(红色,rc);
G.SetClip(rc);
G.TranslateTransform(rc.Left,rc.Top);//原点现在位于(200200)
foreach(行中的行)
{
线条。绘制(G,颜色。蓝色);
}
}
}

,(以及所有相关转换),(更多…)到
图形的输出是输出的结束。但在此之前,您可以添加更多的层,在不同的单元中操作,添加摄影机逻辑(在2d中也很有用)、坐标变换和所需的抽象。所以你可以有两个不同坐标系的平面,它们以某种方式定位在你的2d/3d世界中,并通过摄像机显示在屏幕上。你也可以检查这个方法(很好,非常快)。所有变换(使用矩阵或提供的辅助方法)都可以应用于图形对象和对象。当这些工具结合在一起时,就可以构建许多不同的工具。不指定可应用于画笔和画笔的变换(请参阅关于此的GraphicsPath,使用画笔进行变换)请注意:
Graphics
对象不包含任何图形;它是一种工具,允许您在相关位图上绘制,包括控件的曲面。系统需要在无法控制时绘制所有控件的曲面;因此,必须从系统将调用的一个事件(即
Paint
事件)创建要添加到这些曲面的所有内容。对于从
control.CreateGraphics()
获取的
graphics
对象,只有非持久性图形操作(如显示动态橡皮筋矩形)才可以。没有绘图的测量…另外:您不能缓存图形对象,但可以存储和恢复当前设置,包括比例和平移。。
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);
        }
    }

}