2012-05-04 10 views
6

Mam DrawingVisual element, który rappresents ścieżkę, która geometria jest opisana w niniejszym syntax:Bug w geometrii Hit-Testing

„m106,59.3c0-1.98,0,0-4.95,0.989-3.96, 0,989-138,8,3.96-20,8,4.95-62,92,0-14.8-3.96-17.8-3.96-1.928.97,3.96,10.9,7.91,13, 29.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”

do renderowania wizualny używam MyCanvas klasę, która zapewnia funkcjonalność hit-testing:

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; } 
    } 
} 

Kiedy rysuję mój (czerwony) Ścieżka ta jest wynikiem:

przypadku gdy wielkość komórek siatki jest 50x50. Teraz próbuję uzyskać wizualizacje na przykład w tym regionie:

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); 

Ale MyPath nie jest wynikiem, dlaczego? Jak muszę poprawnie wykonać test trafień? Dzięki.

+0

Czy sprawdziłeś, czy Ścieżka w ogóle nie trafiła w Twój HitTestCallback (ustaw punkt przełomowy)? Jeśli tak, to jaką wartość ma karta IntersectionDetail? – Clemens

+0

Edytuję pytanie (i zapomniałem transformacji) w każdym razie: IntersectionDetail.Intersect – gliderkite

+0

@Clemens Mogłem znaleźć [coś] (http://stackoverflow.com/questions/10453095/rendertransform-vs-pushtransform). – gliderkite

Odpowiedz

5

Wygląda na to, że hit-testing rozpatruje położenie kształtów, do których zastosowano reverse order of transformations. To tłumaczyłoby, dlaczego moja ścieżka jest przecinana, a nie argumentem.

Oczekiwanie na lepsze odpowiedzi, i wdrożył HIT-testuz nie trafić testowania metody, obecnie część MyCanvas Klasa:

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; 
} 

EDIT:

Jak wyjaśnia Mike Danes (moderator na forum MSDN) w wątku this:

"Czy to naprawdę możliwe, że jest to błąd w testowaniu geometrii?"

Jestem w 99% pewien, że to błąd. Testowanie rysunków i trafień powinno wykorzystywać tę samą kolejność przekształcania. Powodem, dla którego działa poprawnie z TransformGroup jest to, że w ten sposób wciskasz tylko jedną transformację w kontekście rysunku, co pozwala uniknąć niewłaściwego porządku mnożenia w kontekście rysowania testu trafienia. Należy pamiętać, że nie ma to nic wspólnego z tym, że kolejność stosowana w TranformGroup różni się od zamówienia push.

+0

Czy możesz zgłosić ten błąd w firmie Microsoft? – DaveInCaz