Określanie części wspólnej obszarów

0

Cześć, pisze aplikacje w WPF i natknąłem na problem którego nie mogę ruszyć w żaden sposób. W jednym z okien aplikacji uzytkownik ma mozliwosc pozycjonowania dwu obiektów względem siebie (testowo sa to dwa czworokąty, zapisane jako kształty typu Path), za pomoca myszy, użytkownik moze je przesuwac i obracać. Problem jaki napotkałem to to, że gdy jeden kształt zostaje nałożony na drugi to częśc wspólna powinna zostać zaznaczona graficznie np innym kolorem (ponadto potrzebowałbym jeszcze policzyc proporcjonalne pole powierzchni czesci wspolnej do powierzchni calkowitej obydwu kształtów).

Znalazłem funkcję która wydaje się ze mogłaby mi pomóc - FillContainsWithDetail. Ale nie wiem jak to polaczyc ze zmianą polozenia kształtu. Generalnie "PathGeometry Figures = "M 485.71429 360.93363....."" to są stałe wspolrzedne kształtu, a zeby uzyc funkcji FillContainsWithDetail, potrzebuje (wg mnie) aktualnej pozycji kazdego wierzchołka danej figury, aby go porownac z polozeniem wierzchołków drugiej figury.

Myslałem nad tym, aby jakos przetransformować wspolrzedne wierzcholkow w obydwu kształtach funkcja TransformToVisual a po zmianie polozenia jednego obiektu uzywac funkcji FillContainsWithDetail, ale nie potrafie tego ogarnac...

Fragment xamla z dwoma obiektami:

<Canvas Name="root" Margin="5,0,-3,0">
            <Path Name="pathA" StrokeThickness="1" Fill="Red" Stroke="#FF000000" StrokeLineJoin="Miter" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" Height="120" Stretch="Fill" Width="175" Canvas.Left="20" Canvas.Top="110">
                <Path.Data>
                    <PathGeometry Figures="M 485.71429 360.93363 237.14286 355.21935 240 520.93363 l 248.57143 2.85715" FillRule="evenodd"/>
                </Path.Data>
            </Path>
            <Path x:Name="pathB" StrokeThickness="1" Fill="Blue" Stroke="#FF000000" StrokeLineJoin="Miter" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" Height="105" Stretch="Fill" Width="170" Canvas.Left="240" Canvas.Top="65">
                <Path.Data>
                    <PathGeometry Figures="m 514.28571 483.79078 -257.14285 2.85714 -2.85715 222.85714 271.42858 0 z" FillRule="evenodd" />
            </Path.Data>
            </Path>
</Canvas> 

To co mam w tym momencie:
a84572319e.png

To co chciałbym uzyskac:
2af47423fa.png

Pomoże ktoś nakierować na właściwy tor rozwiązania?

0

Spróbuj pobrać przetransformowaną już geometrię z właściwości pathA.RenderedGeometry, pathB.RenderedGeometry i użyć jej z FillContainsWithDetail.

0

Próbowałem tak robić juz wczesniej, sęk w tym, że współrzędne w pathA.RenderedGeometry po translacji obiektu sa w dalszym ciągu te same... Właśnie to jest tym moim problemem ze chce porownac wspolrzene juz zaktualizowane a ich w zaden sposob nie moge dostac...

0

Spróbuj prostokątowi rysowanemu w drugiej kolejności ustawić przezroczystość - na pół przezroczysty.

0

Po ustawieniu przezroczystosci efekt wizualny moze i jest taki jak jak powinien byc, ale tutaj chodzi bardziej o "matematyczne" wyznaczenie tego obszaru i na podstawie tego narysowanie obszaru, bo jak wyznaczyć proporcjonalna powierzchnie nałozonych kształtów do calosci poprzez sama transparentnosc?

1

Okej, pozycjonujesz kształty za pomocą współrzędnych na canvasie, a współrzędne geometrii do renderowania są w lokalnym układzie współrzędnych poszczególnych kontrolek path, więc wystarczy przetransformować geometrię o przesunięcie na canvasie z zachowaniem obecnych transformacji, plus minus takie coś:

 
var rga = pathA.RenderedGeometry;
var tga = new TransformGroup();
tga.Children.Add(rga.Transform);
tga.Children.Add(new TranslateTransform(Canvas.GetLeft(pathA), -Canvas.GetTop(pathA)));
rga.Transform = tga;

var rgb = pathB.RenderedGeometry;
var tgb = new TransformGroup();
tgb.Children.Add(rgb.Transform);
tgb.Children.Add(new TranslateTransform(Canvas.GetLeft(pathB), -Canvas.GetTop(pathB)));
rgb.Transform = tgb;

var r = rga.FillContainsWithDetail(rgb);

if (r == IntersectionDetail.Intersects)
{
    PathGeometry com = Geometry.Combine(rga, rgb, GeometryCombineMode.Intersect, Transform.Identity);
    double d = com.GetArea();               
}
0

Wszystko jasne... Zamiast zmieniać połozenie canvasa z lokalnymi współrzednymi chciałem edytować Od razu położenie geometrii, dzięki wielki za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1