2010-04-20 3 views
3

그래프를 WinForms Picturebox에 그려 넣습니다. 이제 나는 선 (점의 배열)을 '복제'할 수있는 가능성을 찾고 있는데, 결과적으로 두 선이 원래 선과 일정한 거리를두고 배치됩니다. 이 그림에서처럼, 나는 빨간 선이 있고 검은 사람 싶어 :Mitrejoin을 사용하여 안내선 주위에 선 만들기

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

난 그냥 라인을 업/최대 오른쪽,하지만 그 이상으로 잘 리드/몇 픽셀을 움직이는 생각을 겹치는 선.

내가 원하는 것을 수행하는 다른 방법이 있습니까? 어떤 아이디어라도 대단히 감사하겠습니다. 감사!

+0

주를이 검정색 선은 빨간색과 같은 크기가 아닙니다. – SLaks

답변

2

정확히을 작성한 함수를 몇 달 전에 그래프 레이아웃 알고리즘의 일부로 만들었습니다. 나는 파이썬과 PyQt에서 그것을 썼다. 방금 코드 here at codepad을 붙여 넣었습니다. 그것은 매우 쉽게 C#으로 번역 할 수 있어야합니다.

업데이트 :

번역이 일대일 내 파이썬 예제 코드 (사랑이해야 할 그래픽 물건 : 그). 필자의 원래 코드는 두 개 이상의 출력 라인을 위해 설계 되었기 때문에 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

+0

그건 아주 유망한 것 같습니다. 저는 파이썬에 대한 단서가 없습니다. –

+0

와우, 끝내 줘! 대단히 고마워, 내가 찾고 있던 완벽하고 정말 빠르고 상세한 답변이다! –

관련 문제