Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Hanz 16. 02. 2015, 16:42:29

Název: C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Hanz 16. 02. 2015, 16:42:29
Dobry den, můžete mi prosim poradit?

Mam nasledujici kod pro vypocet kontaktu rectangle s circle ve wpf. WPF uz narozdil od WinForms nenabizi metodu IntersectWith - jinak by to bylo jednoduche.

Kód: [Vybrat]
public class BrickInfo
    {
        public BrickInfo(int left, int top, int right, int bottom)
        {
            this.left = left;
            this.top = top;
            this.right = right;
            this.bottom = bottom;

            width = right - left;
            height = bottom - top;

            visible = true;
        }

        public int left;
        public int top;
        public int right;
        public int bottom;

        public bool visible;

        private int width;
        private int height;

        public bool IntersectWithCircle(int x, int y, int radius, out MarginTouch margin)
        {

            margin = MarginTouch.Vertical;

            int circleR = radius;

            int circleDistanceX = Math.Abs(x - left);
            int circleDistanceY = Math.Abs(y - top);

            if (circleDistanceX > (width / 2 + circleR))
            {
                return false;
            }
            if (circleDistanceY > (height / 2 + circleR))
            {
                return false;
            }

            if (circleDistanceX <= (width / 2))
            {
                margin = MarginTouch.Vertical;
                return true;
            }
            if (circleDistanceY <= (height / 2))
            {
                margin = MarginTouch.Horizontal;
                return true;
            }

            int cornerDistance_sq = (circleDistanceX - width / 2) ^ 2 +
                                 (circleDistanceY - height / 2) ^ 2;

            return (cornerDistance_sq <= (circleR ^ 2));
        }

    }

Jedna se o počítačovou hru - sestrelovacku - zatím v zakladni verzi. S následujícím kodem mam problém, ze hlavni metoda funguje stoprocentne u objektu, které se nachazi nahore, ale u podlozky, která se nachazi dole (něco jako Arkanoid), vraci false, když by nemela - tedy prunik tam je.

Nevite prosim, cim by to mohlo byt?
H.
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Kolemjdoucí 16. 02. 2015, 17:58:24
Protože se místo obdélníku kontroluje jenom levý horní roh.

Zkusil bych to spíše takto, obdélník musí mít hrany rovnoběžné s osami x a y a kruh se nesmí dostat dovnitř celý:

Kód: [Vybrat]
bool TestLineHorizontal(int x1, int x2, int y, int circle_x, int circle_y, int circle_d)
{
    if (abs(circle_y - y) > circle_d) return false;

    double temp = sqrt((double) (circle_d*circle_d - (y - circle_y)*(y - circle_y))) + circle_x;
    return ((temp >= x1) && (temp <= x2));
}

bool TestLineVertical(int x, int y1, int y2, int circle_x, int circle_y, int circle_d)
{
    if (abs(circle_x - x) > circle_d) return false;

    double temp = sqrt((double) (circle_d*circle_d - (x - circle_x)*(x - circle_x))) + circle_y;
    return ((temp >= y1) && (temp <= y2));
}

bool Test(int x1, int y1, int x2, int y2, int circle_x, int circle_y, int circle_d)
{
    int z;
    if (x2 < x1)
    {
        z = x1;
        x1 = x2;
        x2 = z;
    }
    if (y2 < y1)
    {
        z = y1;
        y1 = y2;
        y2 = z;
    }
   
    bool b1 = TestLineHorizontal(x1, x2, y1, circle_x, circle_y, circle_d);
    bool b2 = TestLineHorizontal(x1, x2, y2, circle_x, circle_y, circle_d);
    bool b3 = TestLineVertical(x1, y1, y2, circle_x, circle_y, circle_d);
    bool b4 = TestLineVertical(x2, y1, y2, circle_x, circle_y, circle_d);

    return (b1 || b2 || b3 || b4);
}

unsigned int main()
{
    bool r = Test(4,4,8,8, 6,10,2);
    printf("%d", (int) r);
}
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Radek Miček 16. 02. 2015, 18:13:03
Může být kruh uvnitř obdélníku nebo obdélník uvnitř kruhu? Potřebujete MarginTouch (co když se kruh dotýká rohu)?

Jinak pravdu má Kolemjdoucí, zkuste si dosadit left=0, top=0, width=4, x=4, y=0, radius=1 (tj. obdélník šířky 4 a kruh má střed v jeho pravém horním rohu). Pak podmínka circleDistanceX > (width / 2 + circleR) je vyhodnocena jako (4 > 2 + 1).
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Hanz 16. 02. 2015, 19:49:24
Děkuji Vám. H.
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: P_V 17. 02. 2015, 14:16:48
Jestli ta podložka je rovná a bez naklápění, tak aproximuj kulatý objekt čtvercem.
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Hanz 17. 02. 2015, 19:10:08
Mám:

Kód: [Vybrat]
public bool IntersectWithCircle(int circleX, int circleY, int circleRadius, out MarginTouch margin)
        {
            margin = MarginTouch.Vertical;

            if (((circleX + circleRadius) >= left) && ((circleX + circleRadius) <= right))
            {
                if ( ( (circleY + circleRadius) <= top) && ( ( circleY + circleRadius)  >= bottom ) )
                {
                    margin = MarginTouch.Horizontal;
                   
                    return true;
                }
            }

            if (((circleY + circleRadius) >= top) && ((circleY + circleRadius) <= bottom))
            {
                if (((circleX + circleRadius) <= left) && ((circleX + circleRadius) >= right))
                {
                    margin = MarginTouch.Vertical;

                    return true;
                }
            }

            return false;
        }

ale někde je chyba. Vidíte ji, prosím?

Děkuju
H.
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Dor 19. 03. 2015, 16:32:19
Moc jsem to nestudoval, ale čekal bych, že tam někde bude taky circleX - circleRadius a circleY - circleRadius, což jsem tam nenašel. Předpokládám, že se ve skutečnosti neřeší kolize s kruhem, ale s pomyslným čtvercem, do kterého je ten kruh vepsaný. Pak taky to vracení jedné hodnoty pomocí out a druhé pomocí return je takové nepěkné. Co takhle returnem vracet jeden objekt/struktura, ve kterém by bylo obojí?
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Dftzjgdr 19. 03. 2015, 19:00:11
A tohle je presne ta situace, ktera se ve foru uz nescetnekrat resila, zda programator potrebuje matematiku a studium.
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: fvesfesrgzdsf 19. 03. 2015, 19:39:19
http://stackoverflow.com/questions/1073336/circle-line-segment-collision-detection-algorithm

http://math.stackexchange.com/questions/261336/intersection-between-a-rectangle-and-a-circle
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: Kolemjdoucí 19. 03. 2015, 21:43:35
A tohle je presne ta situace, ktera se ve foru uz nescetnekrat resila, zda programator potrebuje matematiku a studium.

Na matematiku zatím vůbec nedošlo, stačilo použít zdravý selský rozum.

Mnohem zajímavější je sledovat myšlení tazatele, přestože dostal poměrně funkční kus kódu tak stejně si to umatlal znovu sám jinak špatně ;D
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: fvesfesrgzdsf 20. 03. 2015, 06:57:24
>>Na matematiku zatím vůbec nedošlo, stačilo použít zdravý selský rozum.

a myslite si, ze plus, minus, rovna se neni matematika?!
co jeste patri do selskeho rozumu a ne do matematiky, integral, derivace, grupy, geometrie?!!!
Název: Re:C# - prunik vizualnich objektu (IntersectWith) ovsem ve WPF
Přispěvatel: trrrrrrrrr 20. 03. 2015, 08:45:35
Na matematiku zatím vůbec nedošlo, stačilo použít zdravý selský rozum.


A co to je když ne matematika? Není jedno jestli se výpočet píše tužkou na papír, nebo se ten samý výpočet píše do počítače?
Mimochodem, četl jsem, že každý fungující počitačový program je nějakým způsobem ekvivalentní matematickému důkazu. Na podrobnosti se podívám a když tak je sem napíšu.