2012-05-04 33 views
6

我有一個DrawingVisual元素rappresents其幾何形狀由這個syntax描述的路徑:錯誤在幾何命中測試

「m106,59.3c0-1.98,0,0-4.95,0.989-3.96, 0.989-13.8,3.96-20.8,4.95-6.92,0-14.8-3.96-17.8-3.96-1.98,2.97,3.96,10.9,7.91,13.8,2.97,1.98,9.89,3.96,14.8,3.96,4.95-0.989, 10.9-2.97,13.8-6.92,2.97-2.97,5.93-10.9,6.92-12.9z」

要渲染的視覺我使用MyCanvas類,它提供命中測試功能:

public class MyCanvas : Panel 
{ 
    public List<Visual> Visuals = new List<Visual>(); 
    private List<DrawingVisual> Hits = new List<DrawingVisual>(); 

    public void AddVisual(Visual Visual) 
    { 
     this.Visuals.Add(Visual); 
     base.AddVisualChild(Visual); 
     base.AddLogicalChild(Visual); 
    } 

    public List<DrawingVisual> GetVisuals(Geometry Region) 
    { 
     GeometryHitTestParameters Parameters = new GeometryHitTestParameters(Region); 
     this.Hits.Clear(); 
     HitTestResultCallback Callback = new HitTestResultCallback(this.HitTestCallBack); 
     VisualTreeHelper.HitTest(this, null, Callback, Parameters); 

     return this.Hits; 
    } 

    private HitTestResultBehavior HitTestCallBack(HitTestResult Result) 
    { 
     GeometryHitTestResult GeometryRes = (GeometryHitTestResult)Result; 
     DrawingVisual DVisual = Result.VisualHit as DrawingVisual; 

     if (DVisual != null && GeometryRes.IntersectionDetail == IntersectionDetail.FullyInside) 
      this.Hits.Add(DVisual);  

     return HitTestResultBehavior.Continue; 
    } 

    protected override Visual GetVisualChild(int Index) 
    { return this.Visuals[Index]; } 

    protected override int VisualChildrenCount { 
     get { return this.Visuals.Count; } 
    } 
} 

當我畫我的(紅色)路徑是這樣的結果:

其中網格單元的尺寸50×50是。現在我嘗試在此區域獲取視覺效果:

MyCanvas my_canvas = new MyCanvas(); 
RectangleGeometry MyRegion = new RectangleGeometry(new Rect(50, 50, 250, 250)); 
DrawingVisual MyPath = new DrawingVisual(); 

using (DrawingContext context = MyPath.RenderOpen()) { 
    context.PushTransform(new TranslateTransform(50, 50)); 
    context.PushTransform(new ScaleTransform(2, 2)); 
    context.DrawGeometry(Brushes.Red, new Pen(), MyGeometry); 
} 

my_canvas.AddVisual(MyPath); 
List<DrawingVisual> result = my_canvas.GetVisuals(MyRegion); 

但是MyPath不在結果中,爲什麼?我該如何正確進行命中測試? 謝謝。

+0

你在HitTestCallback(設置斷點)時是否檢查路徑是否全部命中?如果是,IntersectionDetail有什麼價值? – Clemens

+0

無論如何,我編輯的問題(我忘記了轉換):IntersectionDetail.Intersect – gliderkite

+0

@Clemens我可能已經找到[東西](http://stackoverflow.com/questions/10453095/rendertransform-vs-pushtransform)。 – gliderkite

回答

5

看起來好像命中測試考慮應用的形狀的位置reverse order of transformations。這可以解釋爲什麼我的路徑只是相交的,而不是fully inside 方法的參數MyCanvas.GetVisuals方法。

等待更好的反應,我實現了命中測試未命中測試方法,現在MyCanvas類的一部分:

public List<DrawingVisual> GetVisuals(Rect Area) 
{ 
    this.Hits.Clear(); 

    foreach (DrawingVisual DVisual in this.Visuals) { 
     if (Area.Contains(DVisual.DescendantBounds)) 
      this.Hits.Add(DVisual); 
    } 

    return this.Hits; 
} 

編輯:

正如Mike Danes(MSDN論壇主持人)在this中解釋的線程:

「這真的可能是幾何命中測試中的一個缺陷?」

我99%確定這是一個錯誤。繪圖和命中測試應該使用相同的變換順序。它與TransformGroup正確工作的原因是因爲這種方式只能在繪圖上下文中只推送一個變換,並避免了在命中測試圖形上下文中錯誤的乘法順序。 請注意,這與TranformGroup中使用的順序與推送順序不同的事實無關。

+0

你可以在微軟的某個地方提交這個bug嗎? – DaveInCaz