2012-05-04 18 views
6

Tengo un elemento DrawingVisual que rappresents un camino que la geometría se describe mediante este syntax:Bug en la geometría Hit-Testing

"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"

Para hacer que el visual yo uso MiCanvas clase, que proporciona la funcionalidad de prueba de posicionamiento:

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

cuando dibujo mi camino (rojo), este es el resultado:

Cuando el tamaño de las celdas de la malla es de 50x50. Ahora trato de obtener imágenes por ejemplo en esta región:

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

Pero MyPath no está en el resultado, ¿por qué? ¿Cómo debo hacer una prueba de golpe correctamente? Gracias.

+0

¿Ha comprobado si la ruta se golpea en absoluto en su HitTestCallback (establecer un punto de interrupción)? Si lo es, ¿qué valor tiene el IntersectionDetail? – Clemens

+0

Edito la pregunta (olvidé las transformaciones) de todos modos: IntersectionDetail.Intersect – gliderkite

+0

@Clemens Pude haber encontrado [algo] (http://stackoverflow.com/questions/10453095/rendertransform-vs-pushtransform). – gliderkite

Respuesta

5

Parece que prueba de golpe considera que la posición de las formas a la que se aplicó reverse order of transformations. Esto explicaría por qué mi ruta solo se cruza y no fully inside el argumento RectangleGeometry del método MyCanvas.GetVisuals.

A la espera de una respuesta mejor, he implementado el hit-test con un no afectada pruebas método, ahora parte de MyCanvas clase:

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:

Como Mike Danes (moderador en el foro de MSDN) explica en this hilo:

"¿Es realmente posible que esto sea un error en la prueba de detección de geometría?"

Estoy 99% seguro de que esto es un error. Las pruebas de dibujo y golpe deben usar el mismo orden de transformación. La razón por la que funciona correctamente con TransformGroup es porque de esta manera solo se empuja una sola transformación en el contexto de dibujo y esto evita el orden de multiplicación incorrecto en el contexto del dibujo de prueba de golpe. Tenga en cuenta que esto no tiene nada que ver con el hecho de que el orden utilizado en TranformGroup es diferente del pedido de inserción.

+0

¿Se puede archivar este error con Microsoft en alguna parte? – DaveInCaz