gpt4 book ai didi

c# - 使用 Miterjoin 围绕引导线创建线

转载 作者:行者123 更新时间:2023-11-30 17:22:34 25 4
gpt4 key购买 nike

我正在将图形绘制到 WinForms Picturebox 中。现在我正在寻找“复制”一条线(一组点)的可能性,以便两条结果线与原始线相距固定距离。就像在这张照片中,我有红线,想要得到黑线:

Picture of lines http://img227.imageshack.us/img227/2341/linesb.png

我考虑过将线向上/向右/向右移动几个像素,但这会导致出现奇怪的重叠线。

还有其他方法可以满足我的要求吗?任何想法将不胜感激。谢谢!

最佳答案

几个月前,我创建了一个函数,它完全是您需要的,作为图形布局算法的一部分。我用 python 和 PyQt 写的。我刚刚粘贴了代码 here at codepad .这应该很容易翻译成 c#。

更新:

从我的 python 片段中一对一翻译它(喜欢做那些图形的东西 :))。由于我的原始代码是为两个以上的输出行设计的,所以我也将其带入了 c# 版本。对于距离红线 20 像素的两条黑线,只需传递 width = 40num = 2。返回的锯齿状数组表示一个线数组(外部数组),每条线由一个点数组(内部数组)表示。

public PointF[][] MultiplyLine(PointF[] line, int width, int num)
{
if (num == 1) return new PointF[][] { line };
if (num < 1) throw new ArgumentOutOfRangeException();
if (line.Length < 2) return Enumerable.Range(0, num)
.Select(x => line).ToArray();

Func<float, float, PointF> normVec = (x, y) => {
float len = (float)Math.Sqrt((double)(x * x + y * y));
return len == 0 ? new PointF(1f, 0f) : new PointF(x / len, y / len);
};

PointF[][] newLines = Enumerable.Range(0, num)
.Select(x => new PointF[line.Length]).ToArray();

float numinv = 1f / (float)(num - 1), cor = 0f;
PointF vec1 = PointF.Empty, vec2 = PointF.Empty, vec3 = PointF.Empty;

int j = -1, i = -1;
foreach (PointF p in line)
{
bool first = j == -1, last = j == line.Length - 2; j++;

if (!last)
vec1 = normVec(line[j + 1].Y - p.Y, -line[j + 1].X + p.X);
if (!first)
vec2 = normVec(-line[j - 1].Y + p.Y, line[j - 1].X - p.X);
if (!first && !last)
{
vec3 = normVec(vec1.X + vec2.X, vec1.Y + vec2.Y);
cor = (float)Math.Sin((Math.PI -
Math.Acos(vec1.X * vec2.X + vec1.Y * vec2.Y)) / 2);
cor = cor == 0 ? 1 : cor;
vec3 = new PointF(vec3.X / cor, vec3.Y / cor);
}

i = -1;
foreach (PointF[] newLine in newLines)
{
i++; cor = (float)width * ((float)i * numinv - 0.5f);
vec1 = first ? vec1 : last ? vec2 : vec3;
newLine[j] = new PointF(vec1.X * cor + p.X, vec1.Y * cor + p.Y);
}
}

return newLines;
}

为了尝试,我使用了这个小示例(与我的 PyQt 代码中的示例相同):

PointF[] pts = new PointF[] { 
new PointF(100f, 100f), new PointF(300f, 200f),
new PointF(500f, 200f), new PointF(300f, 500f),
new PointF(600f, 450f), new PointF(650f, 180f),
new PointF(800f, 180f), new PointF(800f, 500f),
new PointF(200f, 700f)
};

pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
using(Graphics g = Graphics.FromImage(pictureBox1.Image)){
g.DrawLines(new Pen(Color.Red), pts);

foreach (PointF[] line in MultiplyLine(pts, 80, 14))
g.DrawLines(new Pen(Color.Black), line);
}

这导致了这个图形:

outlines around line http://img41.imageshack.us/img41/8606/lines2.th.png

关于c# - 使用 Miterjoin 围绕引导线创建线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2671698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com