winform坐标系起始位置及象素点显示问题

问题1
将winform坐标系(0,0)从右上角转换成左下角(0,0)?

img

目前我通过将画的方式将坐标系生成在左下角,但是 winfrom的真实坐标还是从 右上角 0,0 开始,并不是从左下角 (0,0)开始

img

问题2
按系统分辨率来生成坐标像素点,如我精确到1个象素一个点,那网格就非常的多,也无法看出所画出的圆,有没有什么方法来进行缩放,同时可以将象素点放大?

img

如悬赏不够的,可以私信我,我可以再追加一点点

TechWhizKid参考GPT回答:

问题1:
在 Winforms 中,你可以在绘制的时候改变坐标系统,使其以左下角为 (0,0)。这可以通过设定转换矩阵实现。下面是一个例子:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;

    // 保存原始状态
    Matrix originalTransform = g.Transform;

    // 创建一个新的矩阵并应用翻转和平移变换
    Matrix transform = new Matrix();
    transform.Scale(1, -1); // 翻转 y 轴
    transform.Translate(0, -ClientSize.Height); // 平移

    // 应用转换
    g.Transform = transform;

    // 在新坐标系下绘制
    g.DrawLine(Pens.Red, 0, 0, 100, 100);

    // 恢复原始状态
    g.Transform = originalTransform;
}

这段代码首先保存了原始的 Graphics.Transform,然后创建了一个新的 Matrix 并设置了翻转和平移,这样 (0,0) 就位于左下角了。然后将这个新的转换应用到 Graphics 对象上,并在新的坐标系下绘制。最后,恢复了原始的 Graphics.Transform。

问题2:
你可以使用 Graphics 对象的 ScaleTransform 方法来进行缩放。这个方法会修改 Graphics 对象的当前转换,使得所有后续的绘制操作都会被缩放。

以下是一个示例代码:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;

    // 缩放
    float scaleFactor = 0.5f; // 缩放比例,可以根据需要进行调整
    g.ScaleTransform(scaleFactor, scaleFactor);

    // 绘制一个圆,位置 (100, 100),半径50
    g.DrawEllipse(Pens.Red, 100 - 50, 100 - 50, 100, 100);
}

在这个示例中,ScaleTransform 方法用于缩放绘制操作。缩放比例由 scaleFactor 控制,你可以根据需要调整这个值。例如,你可以设置一个较小的 scaleFactor 值以缩小绘制的图像,或者设置一个较大的 scaleFactor 值以放大绘制的图像。

这些操作都可以结合起来,先应用一个平移变换以改变坐标系的原点,然后应用一个缩放变换以改变绘制的大小。

其实吧。。。对于这样的场景。。你不要纠结于窗口坐标。
对于有自己的画布这种场景,你的坐标系肯定是不只有一个的。你得定义一个你自己的画布坐标系,
然后再将你的画布绘制在窗体中。我认为这才是一个比较好的思路。而如果你没有定义自己的坐标系统,那么你是否考虑过另外一个问题?DPI?如果要适应DPI那么你又应该怎么处理呢?所以说 自定义坐标系一个是方便管理,而是它可以与设备无关。
就好比 你把你的坐标系统定义成一个图片 你所有的绘制 绘制在这个图片上 然后再把图片绘制到窗口上。
记得好久以前 做了一个类似的DEMO
https://download.csdn.net/download/crystal_lz/4696976?spm=1001.2014.3001.5503

感谢各位的回复,这种翻转,将所有的文字也都翻转了

img

并且缩放也都无效,缩放我是在要在画好之后上面进行缩小,使用过以下方式,但是效果很差


            //Panel pnl = sender as Panel;

            //float fZoomFactor = 1.2f;      // 缩放因子
            //int iOriginCentorX = (pnl.Width / 2 - picCanvas.Left);      //缩放前
            //int iOriginCentorY = (pnl.Height / 2 - picCanvas.Top);

            ////防止无限制的缩放*
            //if ((picCanvas.Width < 400 && e.Delta < 0) || (picCanvas.Width > 22000 && e.Delta > 0))
            //    return;

            //if (e.Delta > 0)//判断放大还是缩小
            //{
            //    //缩放后的picture box的大小。
            //    picCanvas.Width = (int)(fZoomFactor * picCanvas.Width);
            //    picCanvas.Height = (int)(fZoomFactor * picCanvas.Height);
            //    //缩放后的中心点距离picture box左上角的距离。
            //    int iNewCentorX = (int)(iOriginCentorX * fZoomFactor);
            //    int iNewCentorY = (int)(iOriginCentorY * fZoomFactor);

            //    //缩放后的滚轮的位置。
            //    pnl.AutoScrollPosition = new Point((int)(iNewCentorX - pnl.Width / 2),
            //        (int)(iNewCentorY - pnl.Height / 2 + e.Delta));
            //}
            //else
            //{
            //    picCanvas.Width = (int)(picCanvas.Width / fZoomFactor);
            //    picCanvas.Height = (int)(picCanvas.Height / fZoomFactor);

            //    int iNewCentorX = (int)(iOriginCentorX / fZoomFactor);
            //    int iNewCentorY = (int)(iOriginCentorY / fZoomFactor);

            //    pnl.AutoScrollPosition = new Point((int)(iNewCentorX - pnl.Width / 2),
            //        (int)(iNewCentorY - pnl.Height / 2 + e.Delta));
            //}

你是怎么通过将画的方式将坐标系生成在左下角的?你把代码贴出来,才能看到问题。不要只发现象和描述,这样不好定位问题的。

变换Graphics对象的变换矩阵,同时计算绘制坐标时也要将像素值改为原来的一半

问题1:在Form的Paint事件中,重写OnPaint方法,通过Graphics对象的TranslateTransform方法将坐标系平移到左下角的位置。
问题2:如果按照系统分辨率来生成坐标像素点,网格过多导致无法看出所画出的圆,可以考虑使用缩放的方法来解决问题。可以在Form的构造函数中获取屏幕的分辨率,并计算出缩放比例

private void Form1_Load(object sender, EventArgs e)
{
    this.ClientSize = new Size(this.ClientSize.Width, -this.ClientSize.Height);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    int centerX = this.ClientSize.Width / 2;
    int centerY = -this.ClientSize.Height / 2; // 注意Y坐标也需要取负值
    int radius = 50;

    g.DrawEllipse(Pens.Red, centerX - radius, centerY - radius, 2 * radius, 2 * radius);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.ScaleTransform(2, 2); // 将坐标像素点放大两倍

    // 在放大后的坐标系上进行绘制
    int centerX = this.ClientSize.Width / 2;
    int centerY = -this.ClientSize.Height / 2;
    int radius = 50;

    g.DrawEllipse(Pens.Red, centerX - radius, centerY - radius, 2 * radius, 2 * radius);
}

C# winform坐标系类型详解
可以看看

基于new bing部分指引作答:
问题1:
要将 WinForms 的坐标系从右上角转换为左下角,可以通过以下步骤实现:

在 Form 的构造函数中添加以下代码,将坐标系转换为左下角起始位置:

this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
this.ResizeRedraw = true;

在 Form 的 Paint 事件处理程序中,使用以下代码来翻转坐标系:

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphics.ScaleTransform(1, -1); // 上下翻转
    e.Graphics.TranslateTransform(0, -ClientSize.Height); // 平移
    // 绘制其他内容
    base.OnPaint(e);
}

这样,你的坐标系将从左下角开始,而不是右上角。

问题2:
要按照系统分辨率生成坐标像素点,并进行缩放,你可以使用 Graphics 对象的缩放功能。以下是一个示例代码片段,用于绘制一个缩放的圆:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    
    float scaleFactor = e.Graphics.DpiX / 96.0f; // 计算缩放因子,根据系统 DPI
    float radius = 50.0f; // 圆的半径,单位是逻辑像素
    
    // 缩放坐标系
    e.Graphics.ScaleTransform(scaleFactor, scaleFactor);
    
    // 绘制圆
    float centerX = 100.0f; // 圆心 x 坐标
    float centerY = 100.0f; // 圆心 y 坐标
    e.Graphics.FillEllipse(Brushes.Red, centerX - radius, centerY - radius, radius * 2, radius * 2);
}

在上述示例中,通过计算缩放因子 scaleFactor,将绘图表面的坐标系缩放到与系统 DPI 相关的比例。然后,使用缩放后的坐标系绘制圆形。你可以根据需要调整圆的位置、半径以及其他绘图操作。

这样做可以使绘制的图形在不同系统分辨率下进行缩放,并保持一致的视觉效果。

问题1:将 WinForm 坐标系从右上角转换为左下角

默认情况下,WinForm 的坐标系原点位于左上角,水平向右为正方向,竖直向下为正方向。如果你想将坐标系原点从右上角转换为左下角,可以通过以下方式实现:

打开你的 WinForm 窗体,在窗体的构造函数或 Load 事件中添加以下代码:

csharp
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);  // 设置 DPI 为 96
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;  // 根据 DPI 自动调整控件大小
this.RightToLeftLayout = true;  // 启用从右到左布局(反向布局)

this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form_Paint);  // 添加 Paint 事件处理程序

然后在窗体的 Paint 事件处理程序中添加以下代码:

csharp
private void Form_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.ScaleTransform(1, -1);  // 垂直方向翻转坐标系
    e.Graphics.TranslateTransform(0, -this.ClientSize.Height);  // 平移坐标系使原点位于左下角
}

这样做会使绘图时的坐标系原点变为左下角。

问题2:按系统分辨率生成坐标像素点,并进行缩放

要按照系统分辨率生成坐标像素点并进行缩放,可以使用 Graphics 对象的 Transform 属性来实现。以下是一个示例代码:


csharp
private void Form_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.ScaleTransform(scaleFactor, scaleFactor);  // 设置缩放比例

    // 绘制坐标点或其他图形
    // 使用缩放后的坐标进行绘制,例如:g.DrawEllipse(pen, x, y, radius, radius);
}

在上述示例中,需要根据系统分辨率计算出适当的缩放比例 scaleFactor。你可以使用 Screen.PrimaryScreen.Bounds 获取主屏幕的分辨率,并与你所需的最大分辨率进行比较,从而确定缩放比例。

通过设置合适的缩放比例,你可以控制网格的密度和象素点的大小。这样就可以在不失真的情况下进行缩放和显示。

希望对你有所帮助!如果你有任何进一步的问题,请随时提问。

以下答案参考newbing,回答由博主波罗歌编写:
问题1:将winform坐标系(0,0)从右上角转换成左下角(0,0)可以通过以下步骤实现:

  1. 打开窗体的属性窗口。
  2. 将RightToLeft属性设置为Yes。

这将会将窗体的坐标系从右上角转换成左下角。

问题2:按照系统分辨率来生成坐标像素点并进行缩放可以通过以下步骤实现:

  1. 使用Graphics对象的ScaleTransform方法来进行缩放。例如,可以使用以下代码将坐标和绘图区域按比例缩放:
    float scale = desiredScale; // 设置缩放比例
    Graphics g = this.CreateGraphics();
    g.ScaleTransform(scale, scale);
    
  2. 在缩放后的绘图区域中使用Graphics对象进行绘制,例如使用g.DrawEllipse来绘制圆。

请注意,这里的desiredScale可以是任何大于0的数值,较大的值会导致更大的绘图区域,而较小的值则会导致更小的绘图区域。

希望以上解答能够帮到你。如果有需要进一步的解释或者示例代码,请告诉我。
如果我的回答解决了您的问题,请采纳!