2012-08-14 5 views
2

Java2D를 사용하여지도를 그려 가고 있습니다. 내지도가 축소되면 내 도로가 인위적인 그림을 그려냅니다.Java2D 그래픽을 사용하여 밀집도가있는 두꺼운 선을 올바르게 그리려면 어떻게합니까?

Road section drawn at sub-county scale with no drawing artefacts

선 스타일을 사용 :

Road section drawn at state scale showing drawing artefacts

이 가까이 확대 도로의 유사한 섹션이 완전한 미국 상태를 그리기 화면의 작은 부분 2 픽셀에 해당하는 너비로 조정 된 실선의 파란색 선입니다. 다양한 렌더링 힌트와 줄 결합 규칙을 시도했지만 아무 도움이되지 않습니다.

OS/X 10.8을 실행하는 Mac에서 Open JDK 1.7을 사용하고 있으며 Sun JDK 1.6이 설치된 Linux 컴퓨터에서도 재현 할 수 있습니다.

모든 모양과 변환은 Java2D에서 가능한 한 배정 밀도입니다. 선의 기하학은 많은 밀집된 점을 가지고 있으며 드로잉의 원인은 렌더러가 하나의 픽셀보다 가까운 연속 된 점에 혼란스러워하고 있다고 생각합니다.

포인트를 줄이지 않고도 축소 된 모양의 모양을 개선 할 수있는 방법이 있습니까?

편집 유물은 별도의 선분이 만나는 지점에서, 그래서 누락 된 픽셀이 끝 점이 동일한 경우에도, 라인 캡 (끝) 충족되지 함께 할 수있는 뭔가하는 도면. 이 이미지는 두 선 세그먼트 사이의 회의 지점을 보여줍니다. 나는 각각의 선분을 7 픽셀 크기의 선 스타일로 강조 표시했다. (XOR-ed with white) 그러나 아주 가까이서 보면 원래의 파란색 선의 일부를 볼 수있다. (둥근 대문자가 겹치고 XOR 드로 모드) 보통의 눈금에서는 끝이 겹쳐지는 것처럼 보입니다. 그러나 일반 페인트 모드에서 축소하거나 축소하면 파선 효과가 나타납니다.

한 가지 해결 방법은 그리기 전에 인접한 모든 선 세그먼트를 함께 연결하는 것이지만 여전히 드로잉 공작물의 실제 원인을 알고 싶습니다.

Join between two road segments

답변

1

난 당신이 OS X 1.6 JDK를 사용하여 한 상황을 재현 할 수없는,하지만 난 여전히 당신을 위해 몇 가지 제안이있다.

상태를 윤곽으로 나타 내기 위해 방금 사용하는 경우 GeneralPath class을 사용해보세요. lineTo(x,y) 방법을 사용하여 회선에서 각 지점을 설정할 수 있습니다. 다시 말하지만, Line2D.Double을 사용하여 문제를 재현 할 수 없기 때문에, 실제로 이것이 다른지는 알 수 없습니다.

둘째, 더 중요한 것은 확대 및 축소하는 방법입니다. 내 Graphics2D 개체에 AffineTransform (with setScaleTo(x,y))을 사용하고 있으며 모든 것이 원활하게 진행되고 있습니다. 확대/축소 요소 (또는 다른 방법으로 수행 할 수있는 것)로 데이터의 점 크기를 조정하는 대신에 매우 쉽습니다.또한 모든 요소의 크기를 조절할 것이기 때문에 요소에 의해 선의 선을 조정해야합니다. 원하는 경우 스크린 샷을 게시 할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 규모 조정과 변환 작업을 결합한 AffineTransform을 사용하고 있습니다. 또한 스트로크 너비를 조절합니다. 내 좌표 중 일부는 5 - 10m 떨어져 있습니다. 축소 된 캔버스의 전체 너비는 약 1,000,000m입니다. Apple 1.6 JDK로 실행되는 이전 버전의 코드로 롤백 할 수 있는지 확인합니다. 도로를 그릴 때 나는 주로 문제를 봅니다. 군 경계는 괜찮아 보이지만 아마도 같은 수준의 세부 사항은 없을 것입니다. – richj

+0

Apple JDK 1.6에서도 문제가 발생합니다. 문제가 라인 내에서 인조 물을 그리는 것과 관련이 없지만 라인 세그먼트의 끝점에서 발생하는지 궁금해지기 시작했습니다. 데이터를 면밀히 살펴보면 도로는 많은 정점이있는 긴 연속 선이 아니라 인접한 종점이있는 더 짧은 선 세그먼트입니다. – richj

+0

이 대답을 받아 들일 때 결국 해결책이되었습니다. 이 레이어의 드로잉 최적화 중 하나를 해제하거나 각 고속도로에서 세그먼트를 함께 결합해야합니다. – richj

1

Xiaolin Wu's line algorithm 당신이 질문에 대답해야 확인하시기 바랍니다!

기본 개념

function plot(x, y, c) is 
plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1) 

function ipart(x) is 
return integer part of x 

function round(x) is 
return ipart(x + 0.5) 

function fpart(x) is 
return fractional part of x 

function rfpart(x) is 
return 1 - fpart(x) 

function drawLine(x1,y1,x2,y2) is 
dx = x2 - x1 
dy = y2 - y1 
if abs(dx) < abs(dy) then     
    swap x1, y1 
    swap x2, y2 
    swap dx, dy 
end if 
if x2 < x1 
    swap x1, x2 
    swap y1, y2 
end if 
gradient = dy/dx 

// handle first endpoint 
xend = round(x1) 
yend = y1 + gradient * (xend - x1) 
xgap = rfpart(x1 + 0.5) 
xpxl1 = xend // this will be used in the main loop 
ypxl1 = ipart(yend) 
plot(xpxl1, ypxl1, rfpart(yend) * xgap) 
plot(xpxl1, ypxl1 + 1, fpart(yend) * xgap) 
intery = yend + gradient // first y-intersection for the main loop 

// handle second endpoint 
xend = round (x2) 
yend = y2 + gradient * (xend - x2) 
xgap = fpart(x2 + 0.5) 
xpxl2 = xend // this will be used in the main loop 
ypxl2 = ipart (yend) 
plot (xpxl2, ypxl2, rfpart (yend) * xgap) 
plot (xpxl2, ypxl2 + 1, fpart (yend) * xgap) 

// main loop 
for x from xpxl1 + 1 to xpxl2 - 1 do 
    plot (x, ipart (intery), rfpart (intery)) 
    plot (x, ipart (intery) + 1, fpart (intery)) 
    intery = intery + gradient 
end function 
+0

+1 위키 백과의 링크는 "한 줄 미만의 선은 특별한 경우로 처리되어야합니다."라고 말합니다. 아티팩트의 가능한 원인으로 서브 픽셀 선분을 구체적으로 언급 할 때이 특수 사례를 처리하는 방법을 정확하게 설명한다면이 기사는 더욱 적절할 것입니다. 낮은 수준의 렌더링 알고리즘이 Java2D API에서 구현 될 것으로 기대됩니다. 내가 찾고있는 솔루션은 Java2D API를 사용하여 연속적이고 두꺼운 선을 만드는 방법을 설명합니다. 유익한 답장을 보내 주셔서 감사합니다. – richj

+0

또 다른 수용 가능한 해결책은 이것이 현재 가능하지 않은 이유를 설명하고 질문에서 제안한 것보다 나은 해결 방법을 제공합니다 (모양을 렌더링하기 전에 점 틴닝). – richj

관련 문제