2009-04-07 4 views
21

우리는 Path 객체를 사용하여 캔버스에 드로잉을 배치하는 것과 같은 CAD 응용 프로그램을 개발하는 데 wpf를 사용하고 있습니다. 나는 캔버스의 모든 요소를 ​​확대/축소 할 때 캔버스의 모든 요소가 크기가 조절되고 이것이 내가 원하는 동작이지만 경로의 획 두께가 증가한다는 약간의 문제가 발생했습니다.스케일에 관계없이 패스의 불변 스트로크 두께

개체를 늘리거나 확대/축소하는 방법은 있지만 경로의 획 두께는 그대로 유지합니다.

이와 관련하여 도움이 될 것입니다.

답변

6

마지막으로 위의 해결 방법에 대한 해결책을 얻었습니다. 나는 Canvas의 비율에 비례하여 PathStrokeThickness을 설정하여이 작업을 수행했습니다. 이처럼

:

// scale = scaling factor applied to the canvas 
path.StrokeThickness = 1.0/scale; 

이 유일한 작품 ScaleXScaleY가 균일합니다. 당신은 참으로 스트로크를 변경할 수 있도록

+13

x와 y 비율은 균일하지만 비늘이 같지 않은 경우에는 문제가 없습니다. – Klay

13

더 나은 솔루션이 당신의 경로를 저장하는 하나 이상의 System.Windows.Media.Geometry 객체를 사용하는 것,

이 기하하는 펜으로 그릴 수 등 지적 두께를 조정할 때 Transform 속성을 사용하는 것이 더 유연합니다.

변환을 사용하면 시각화가 아닌 기하학적 표현의 실제 좌표를 "확대/축소"할 수 있습니다. 그리면 렌더링 할 때 렌더링 변환을 할 필요가 없습니다. fromPosition 사각형이 변환되지 않은 경계를 포함해야하고, toPosition 사각형이 변환 된 경계를 포함해야하는 위치

public static Matrix TransformShape(Rect fromPosition, Rect toPosition, bool flipVertical) { 
    Matrix translateThenScale = Matrix.Identity; 
    //we first translate to origin since that's just easier 
    translateThenScale.Translate(-fromPosition.X, -fromPosition.Y); 
    //now we scale the graph to the appropriate dimensions 
    translateThenScale.Scale(toPosition.Width/fromPosition.Width, toPosition.Height/fromPosition.Height); 
    //then we flip the graph vertically around the viewport middle since in our graph positive is up, not down. 
    if (flipVertical) 
     translateThenScale.ScaleAt(1.0, -1.0, 0.0, toPosition.Height/2.0); 
    //now we push the graph to the right spot, which will usually simply be 0,0. 
    translateThenScale.Translate(toPosition.X, toPosition.Y); 

    return translateThenScale; 
} 

:

내가 좋아하는 다음 코드를 사용하여 변환을 계산합니다. 이것은 또한 X와 Y를 개별적으로 스케일링 할 수있게 해주므로 플로팅에 종종 필요합니다.

그것은 당신의 형상의 경계를 계산하기 쉽다 :

Geometry graphGeom; 
//[...] 
//the bounds are modified by the transform, so we want no transform!  
graphGeom.Transform = Transform.Identity; 
Rect graphBounds = graphGeom.Bounds; 
//then set the transform again 

//or, if the transform is axis-aligned, the following _should_ work: 
Rect graphBoundsAlt = graphGeom.Transform.Inverse.TransformBounds(graphGeom.Bounds); 

그리고 물론 WPF는 당신이 필요 있어야로 렌더링 할 필요가 경계하는 당신에게 말할 수 있습니다. 함께 퍼팅,이 솔루션을 사용의 장점은 당신이 무료로 사용할 수있어, RenderTransforms로 엉망 필요가 없다는 것입니다

public void RecomputeTransform(Rect targetRect, bool flipVertical) { 
    graphGeom.Transform = Transform.Identity; 
    Rect graphBounds = graphGeom.Bounds; 
    Matrix transMat = TransformShape(graphBounds,targetRect,flipVertical); 
    graphGeom.Transform = new MatrixTransform(transMat); 
} 

처럼 뭔가를 할 수는 전단 및/또는 스케일 X 및 Y 변환 펜을 불투명 한 오브젝트로 취급 할 수 있습니다 (즉, UI에서 사용자 정의하기가 더 쉽습니다 - 펜 너비 또는 기타 등을 선택하면 더 이상 수정하지 않아도됩니다).

+0

이 솔루션을 사용하면 크기를 조정할 수있는 메인 캔버스와 분리되도록 그리기 부분을 필요로한다고 가정합니다. 예가 그림 그리기 응용 프로그램이 될 것이지만 도면 자체는 크기가 조정되지만 앵커 포인트는 시각적으로 표시되고 크기는 위치에 따라 다르지만 두께는 다릅니다. 이 가정에서 나는 맞습니까? – jpierson

+0

죄송합니다. 귀하의 질문을 이해하지 못했습니다. 실제로 이것은 이상적인 선이나 점을 염두에두고 그 두께가 아닌 벡터 드로잉 시나리오에서 수행하게 될 것입니다. 이 방법은 선 너비를 변환하지 않고 선 그림을 크기 조정 (또는 선형 변환)합니다. 즉, 당신은 이상화 된 기하학을 변환하고 있으며, 단지 "0"너비의 선을 가진 "진짜"모양으로 변환하는 것입니다. 'Drawing'을 변형 시키려면 line withs와 line joins 등의 세부 사항을 변환해야합니다. 그게 분명해? –

+0

내 생각에, 드로잉 응용 프로그램에는 도면과 같은 모든 부분의 크기를 조절하는 일부 부품과 두께에 따라 확장되지 않지만 크기 조정 된 도면에 상대적으로 배치되는 데코레이터와 같은 일부 부품이 있다고 가정했습니다. 드로잉 선의 두께를 조절하지만 선택된 오브젝트에 대해 표시되는 앵커 포인트는 같은 방식으로 크기가 조정되지 않는 Inkscape와 같은 벡터 드로잉 응용 프로그램과 같은 경우. 그래서 내 가정은. NET에서 이것을 달성하는 것입니다 당신은 여전히 ​​독립적으로 확장됩니다 두 개의 분리 된 패널에 이러한 부분을해야합니다. – jpierson

0

나는 몇 번이나 여기에 왔지만이 아이디어는 나에게 일어났습니다. 단지 Viewbox에 포장하는 것이 어땠습니까?

시도해 볼 수 있습니다. 높이/너비로 어지럽게 만들면 두께와 크기의 비율이 변경되지 않아야합니다. 어쩌면 내가 아직 발견하지 못한 다른 나쁜 일들을 할지도 모른다.

<Viewbox Height="50" Width="50"> 
    <Path Stroke="Black" Fill="Black" StrokeThickness="0.8" Stretch="Uniform" 
       Data="M0,0 20,20" /> 
</Viewbox>