2013-08-07 7 views
1

는 다음 코드를 사용하여 일부 사각형을 만든 : 여기 왜 인접한 직사각형이 밴딩 효과를 생성합니까?

double width = 6.546; 

for (int i = 0; i < 50; i++) 
{ 
    var rect = new Rectangle() 
    { 
     Width = width, 
     Height = i * 10, 
     Fill = Brushes.Blue, 
    }; 

    Canvas.SetLeft(rect, i * width); 
    Canvas.SetBottom(rect, 0); 

    canvas.Children.Add(rect); 
} 

은 결과입니다 밝기 변화의 수직 라인이 있습니다

verticalbanding

. 왜 그들은 나타 납니까? 큰 width 값을 사용하면 이러한 현상을 피할 수 있습니다. 그들을 피할 수있는 다른 방법이 있습니까?

+2

픽셀은 부동 소수점이 아닙니다. 그것들은 필수적입니다. 너비를 정수로 만들어보십시오. 너는 그들을 보지 말아야한다. –

+0

'int width = 6;을 사용하여 테스트 한 결과 밴드가 없습니다. – Shoe

+0

@NotALie .: 'width'를 변경하면 도면의 기울기가 변경되어 원래의 의도를 달성하지 못합니다. –

답변

2

여기서 중요한 문제 Width = width 6의 직사각형 폭을 설정한다는 것이다 (this 참조)하지만의 제품을 절단하여 얻어지는 정수로 (6, 13, 19, 26 ... 0 직사각형의 위치를 ​​Canvas.SetLeft(rect, i * width) 설정 대략 0, 6.546, 13.092, 19.638, 26.184, ...). 보시다시피, 일부 위치는 6 단위 및 13 단위 또는 19 및 26과 같이 7 단위 떨어져 있습니다. 따라서 6 단위 사각형은 7 단위 거리를 확장하지 않습니다.

이 경우 너비를 Width = ceil(width) (7)으로 설정하면 직사각형이 그 사이의 거리를 확장 할 수있을 정도로 넓어집니다.

this answer은 숫자가 int 인 것으로 나타내지 만 바람직하지는 않습니다. 계산을 int으로 변환하는 경우 정수를 정수 (6 또는 7)의 배수로 설정하거나 정수를 사용하여 같은 위치 (0, 6, 13, 19, 26 ...)를 계산하는 방법을 찾아야합니다 부동 소수점 대신 산술. 전자는 산술에 맞게 드로잉을 변경하기 때문에 바람직하지 않습니다. 후자는 도면에서 경사를 유지하지만 동일한 밴딩 문제가 있습니다.

그 대답은 또한 부동 개체 버전의 그리기 개체를 사용하는 것이 좋습니다. 그것은 합리적인 접근법입니다. 그러나 이것은 단순히 정수 단위에서 더 작은 부동 소수점 단위로 반올림 오류를 줄입니다 (이 크기로). 그것들을 제거하지는 못합니다. 대형 도면에서는 회피하지 않도록 조심하지 않으면 가끔 인위적 인조물이있을 수 있습니다. 따라서 세부 정보를 이해하는 것이 중요합니다. 부동 소수점을 사용하는 경우에도 너비가 적어도 위치의 변경만큼 크게 설정되어야합니다.

또 다른 옵션은 드로잉 인터페이스에서 지원하는 경우 캔버스의 배율을 변경하는 것입니다. 배율을 1000 배로 늘릴 수 있지만 최종 배율을 같은 크기로 유지하면 배율이 6.546에서 6546으로 변경되고 너비를 6000 또는 7000 대신 정확히 6546으로 설정할 수 있습니다. 알 수 있듯이 핵심 이슈로 돌아가십시오 : 폭을 적어도 두 위치의 차이만큼 큰 값으로 설정해야합니다.

앞에서 설명한 것처럼 너비를 7로 설정하면이 그림을 사용할 수 있습니다. 제가 다른 해결책을 논의하는 이유는 일부 도면에서 폭을 6.546 이상으로 변경하면 객체 크기가 바람직하지 않게 증가하기 때문입니다. 다른 솔루션은 원하는 크기에 더 가깝게 너비를 유지할 수있게함으로써이를 향상시킵니다.

0

먼저는 문제가 해결 어떻게되는지 쉽게을보고 (Rectangle를 추가하기 전에) 코드이 줄을 추가하십시오! 이 문제 가 아니라 그것 장치 독립적 인 측정 단위라고 WPF에 사용 묘화 시스템에 관한 것이다 부동 소수점 숫자에 관련되지 않고, 내 제를 포함한 어떤 응답하여 설명한 것과

canvas.SnapsToDevicePixels = true; 

달리하지만 96 인치 (dpi)보다 큰 장치에서 아티팩트가 발생할 수 있습니다. Microsoft는이 문제를 기각했습니다.

...이 dpi 독립성은 앤티 앨리어싱으로 인해 불규칙한 가장자리 렌더링을 만들 수 있습니다. 에지의 위치

(Reference)

디바이스 픽셀의 중앙보다는 디바이스 화소 사이 하강하지만 용액에 의해서도 제공 될 때 일반적으로 "소프트"흐릿하거나 모서리로 간주 아티팩트가 발생할 수 SnapToDevicePixels 속성

+0

RectangleF를 사용할 수 없다고 생각합니다. UIElement가 아닙니다. "Canvas에 추가 할 때 'System.Drawing.RectangleF'에서 'System.Windows.UIElement'로 변환 할 수 없습니다. – epalm

+0

예, 맞습니다. 저는 WPF에 익숙하지 않았습니다. 문제를 해결하기 위해 다른 방법을 시도 할 것이고, 나중에 다른 대답을 게시 할 것입니다. – ehsan88

+0

@epalm이 새로운 답변을보고 즐기십시오! – ehsan88