C# GDI+;线描算法
我无法理解GDI+在曲面上画线的方式,可能是它有一些算法 例如,我们取一个10x10 px的表面C# GDI+;线描算法,c#,graphics,gdi+,C#,Graphics,Gdi+,我无法理解GDI+在曲面上画线的方式,可能是它有一些算法 例如,我们取一个10x10 px的表面 Bitmap img = new Bitmap(10, 10); 现在让我们在此曲面上绘制一条线,宽度为5px,顶部偏移为5px using (var g = Graphics.FromImage(img)) { g.Clear(Color.White); var pen = new Pen(Color.Brown); pen.Wi
Bitmap img = new Bitmap(10, 10);
现在让我们在此曲面上绘制一条线,宽度为5px,顶部偏移为5px
using (var g = Graphics.FromImage(img))
{
g.Clear(Color.White);
var pen = new Pen(Color.Brown);
pen.Width = 5;
g.DrawLine(pen, 0F, 5F, 10F, 5F);
}
我们将获得:
绘图不是从像素5开始的,而是从像素4开始的。
很明显,起点是单独计算的。但是怎么做呢
我试着得到一个规律,得到了:
y = offset + width/2 - 1
其中y为实际起点y,偏移为选定的起点y
但在某些情况下,这是行不通的。例如,假设宽度=6,选定的顶部偏移=0,我们将得到y=2,它将按如下方式绘制:
它必须显示6个像素,但它没有显示
因此,必须有更通用的算法来选择起点,但我真的不知道它可以是什么。
感谢您的帮助。在第一个示例中,它看起来像一条宽度为5像素的线,以第5行为中心(计数从0开始,而不是从1开始)。 这似乎是一个合理的结果
在第二个示例中,它看起来像一条宽度为6的线,居中于第1行和第2行之间,在这条线的顶部行被截断,因为它超出了图像的边界。线条图中没有偏移。在
绘制线方法中指定的坐标定义了线的中心。顶部像素为y-width/2
,底部像素为y-width/2+width-1
。第二个公式考虑了width/2
向下舍入的事实。此外,顶行是y=0
,底行是y=9
。因此,对于您来说,第一行:
top = 5 - (5 / 2) = 3
bottom = 5 - (5 / 2) + 5 - 1 = 7
第二行:
top = 2 - (6 / 2) = -1
bottom = 2 - (6 / 2) + 6 - 1 = 4
顶部边缘被剪裁到位图的边缘,因此线宽减小。GDI+中的坐标不指定像素本身,而是指定其中心的(无限小)点。因此(0f,5f)
表示第一列和第六行中像素的中心(因为计数从零开始)。因此,我将从现在开始区分坐标和像素行
在绘制直线时,GDI+概念上沿这些坐标定义的直线移动指定宽度的笔。请注意,您可以通过指定pen.StartCap
和pen.EndCap
在行首和行尾定义此笔的确切形状
由于您指定了宽度5f
并绘制了一条水平线,因此该线将2.5
像素向上和向下延伸,从而覆盖从#3到(包括#7)的完整像素行。注意,根据上述定义,像素行3的上边缘具有y坐标2.5
,行7的下边缘具有7.5
,分别为5f-2.5f
和5f+2.5f
对于第二个示例(我尝试了),我没有得到与您相同的结果。相反,我得到了一条覆盖前三个像素行的线。理论上,它甚至应该覆盖前3.5个船头(因为坐标指定了第一排的中心,所以上面的部分被简单地剪裁)。但如果禁用抗锯齿,底部的“半行”将被截断
这可以通过将g.SmoothingMode
设置为SmoothingMode.AntiAlias
来显示,在这种情况下,第四行是透明绘制的。使用抗锯齿时,您还会注意到,第一列和最后一列没有完全绘制,因为开始坐标同样位于列的中心