Kolizja koła z łukiem

E1
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:17
0

Witam. Męczę się z następującym problemem:

Mam koło i okrąg o identycznym promieniu R. Bardzo łatwo mogę sprawdzić kolizje tych obiektów
na podstawie odległości między środkami. Gorzej jeśli z okręgu wytnę sobie łuk. Taki łuk może mieć długość
od 0 (punkt) do pełnego okręgu.

Jak mogę szybko wykryć kolizje między tymi obiektami ?

Mam środki i mam promień.

Chodzi o koło (a nie okrąg) i łuk (a nie wycinek koła).

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Na oko potrzebne są 2 kryteria:

  1. Klasyczne kryterium które opisałeś, czyli sprawdzenie czy cały okrąg przeciąłby nasze koło
  2. Dodatkowe kryterium które sprawdza czy łuk który mamy przecina koło: trzeba wyznaczyć równania 2 prostych pomiędzy środkiem okręgu a krańcami łuku i sprawdzić czy któraś z tych prostych przecina koło (czyli czy odległość środa koła od prostej jest <= promieniowi koła)

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
E1
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:17
0

Przecinanie się tych prostych z kołem może oznaczać zupełnie nic. Te same proste mogą obydwie przecinać koło i łuk będzie przecinał koło a potem odwracamy łuk i proste dalej przecinają koło a łuk już nie przecina.

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

To by się dało załatwić przez sprawdzenie czy środek okręgu i koniec łuku są po tej samej stronie prostej prostopadłej to prostej która daje nam punkt przecięcia.
Ale w sumie zastanowiło mnie teraz -> nie da sie zwyczajnie rozwiązać równania 2 okręgów z dodatkowymi ograniczeniami wynikającymi z tego że bierzesz tylko wycinek koła?


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0
Shalom napisał(a):

Na oko potrzebne są 2 kryteria:

  1. Klasyczne kryterium które opisałeś, czyli sprawdzenie czy cały okrąg przeciąłby nasze koło
  2. Dodatkowe kryterium które sprawdza czy łuk który mamy przecina koło: trzeba wyznaczyć równania 2 prostych pomiędzy środkiem okręgu a krańcami łuku i sprawdzić czy któraś z tych prostych przecina koło (czyli czy odległość środa koła od prostej jest <= promieniowi koła)

Może zastąpmy drugie kryterium na:
Czy przecinają się odcinki pomiędzy środkami (jeden odcinek) oraz pomiędzy krawędziami luku (drugi odcinek)
- zły pomysł, czytaj komentarz.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 3x, ostatnio: _13th_Dragon
bogdans
Niestety, to jest błędne kryterium.
Shalom
Odpada kiedy łuk sięga "za" środek koła
E1
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:17
0
_13th_Dragon napisał(a):
Shalom napisał(a):

Na oko potrzebne są 2 kryteria:
2. Dodatkowe kryterium które sprawdza czy łuk który mamy przecina koło: trzeba wyznaczyć równania 2 prostych pomiędzy środkiem okręgu a krańcami łuku i sprawdzić czy któraś z tych prostych przecina koło (czyli czy odległość środa koła od prostej jest <= promieniowi koła)

Może zastąpmy drugie kryterium na:
Czy przecinają się odcinki pomiędzy środkami (jeden odcinek) oraz pomiędzy krawędziami luku (drugi odcinek)

Co to jest krawędź łuku ? Dla mnie krawędź łuku to sam łuk. Jeśli chodzi natomiast o połączenie końców łuku to NIE. Jest 9129487926141 przypadków kiedy to nie pasuje.

_13th_Dragon
miałem na myśli końce - dwa punkty ograniczające
szopenfx
  • Rejestracja:prawie 21 lat
  • Ostatnio:4 miesiące
0

Sprawdzenie czy punkt należy do koła jest banalne - wystarczy tylko teraz sprawdzić czy wszystkie punkty łuku zawierają się w kole - tutaj jest ten problem, że nie możesz poprzestać tylko na granicznych punktach łuku bo gdy promień łuku będzie mniejszy od promienia koła oba końce łuku mogą być w środku koła a część wewnętrzna łuku poza nim.

//dopisane
Nie trzeba wszystkich tylko oba skrajne punkty łuku oraz trzeci punkt dwusiecznej łuku

kolo i luk.png

tak jak na rysunku musisz sprawdzić czy wszystkie czerwone pkt. są w środku koła.

//dopisane 2 raz xD
Nie no niestety trzeba sprawdzić wszystkie punkty, albo rozbić to na różne przypadki

edytowany 3x, ostatnio: szopenfx
Shalom
Ale przecież on przecina z kołem a nie okręgiem... Więc nie rozumiem gdzie jest problem w sytuacji że końce łuku są wewnątrz ;]
E1
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:17
0

Potestowałem kolejne pomysły i dalej nic. Zawsze jest jakiś przypadek kiedy działa źle. A znowu rozbijać tego na 10 przypadków nie chce bo to jest mnóstwo przeliczania niepotrzebnych rzeczy.

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Może tak:

  1. obliczamy punkty przecięcia dwóch kół
  2. dla każdego (z max dwóch) sprawdzamy czy ten punkt przecięcia leży po innej stronie cięciwy niż środek kola na którym leży luk. (Po innej -> mamy przecięcie)

Po której stronie jest punkt:
Prosta przez dwa punkty A(Ax,Ay) - B(Bx,By)
Sprawdzamy czy punkty P(Px,Py) oraz C(Cx,Cy) są po różnych stronach prostej

Kopiuj
if(((Ax-Cx)*(By-Cy)-(Ay-Cy)*(Bx-Cx))<0)==((Ax-Px)*(By-Py)-(Ay-Py)*(Bx-Px))>0)) // jeżeli po innej stronie

Ewentualnie trzeba jeszcze rozpatrzyć kiedy A==C lub B==C


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon
Shalom
Bez żartów. Jak już mamy punkt przecięcia tych kół to co za problem zamienić to na współrzędne biegunowe i sprawdzić czy kąt nam się zgadza? Bo bo ja rozumiem że ten łuk jest zadany przez okrąg i zakres kątów.
E1
1) Punkty przecięcia mam. 2) Po innej stronie jakiej cięciwy ? Tej między jego końcami ? Jeśli dobrze rozumiem o co chodzi to sprawdziłem kilka przypadków i nie jest to działający sposób Jeśli chodzi o łuk to mam 3 punkty (środek okręgu którego częscią jest łuk i końce łuku). Łuk zawsze tworzony jest w kierunku przeciwnym do kierunku wskazówek zegara od punktu P1 stąd wiem na przykład czy łuk ma mieć 270 czy 90 stopni. Jakie kąty mam sprawdzić ? Już niejedne sprawdzałem. Narysuj jeśli możesz konkretnie jak to ma działać bo nie rozumiem.
Shalom
Wzór okręgu to x = x0 + rcos(alfa), y = y0 + rsin(alfa). Znasz środek wiec znasz (x0,y0). Znasz promień więc znasz r. Znając punkt przecięcia (x,y) mozesz policzyć sobie kąt alfa. Korzystając znów z wzoru okręgu możesz wyznaczyć zakres kąta alfa dla twojego łuku (liczysz to analogicznie, za pomocą punktów wyznaczających twój łuk). Jeśli kąt punku przecięcia mieści się w wyliczonym zakresie to masz przecięcie, Jeśli nie, to nie.
_13th_Dragon
Będzie z dodatkowym sprawdzeniem w okolicach 360.
E1
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:17
0

Nie do końca podoba mi się rozwiązanie z kątami bo korzystam z funkcji ArcCos które nie są chyba za szybkie i nie wiem jak z dokładnością. Ale może inne rozwiązania są jeszcze gorsze.

W każdym razie na razie tak to zrobiłem i u mnie nawet chyba całość wyszła prościej niż wynikało z opisów. Środek łuku traktuje jako punkt 0,0 i liczę 4 kąty pomiędzy osią X a 4 punktami (2 końce łuku, 2 przecięcia). Jeśli Y danego punktu jest mniejszy niż 0 to robię 'kąt = 360 - kąt' żeby otrzymać pełny zakres kąta. A potem mam dwa przypadki: kąt "końcowego" punktu łuku jest większy od kąta "początkowego" - wtedy którykolwiek z kątów do przecięć musi wypaść pomiędzy tymi kątami, lub kąt "końcowy" jest mniejszy od "początkowego" - wtedy któryś z kątów do przecięć musi miec wartość 0 do kąta "końcowego" lub od kąta "początkowego" do 360 (to ten szczególny przypadek przejścia przez kąt 360). Jest jeszcze jeden przypadek kiedy cały łuk znajduje się wewnątrz koła. Ten przypadek należy wykryć czy odległość środka koła od któregoś z końców łuku nie jest mniejsza lub równa od promienia. Pewnie rysunek byłby bardziej zrozumiały...

MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:8 minut
0

Wyznaczasz przecięcie dwóch okręgów, masz dwa punkty (to na pewno masz zrobione), teraz pozostaje zrobić test czy jeden z tych dwóch punktów znajduje się w granicach łuku, a to można sprawdzać (A,B początek i koniec łuku, O środek łuku X badany punkt:
Jeśli (\vec{OA}\times\vec{OB})&gt;=0 (nie więcej niż pełny półokrąg) to muszą być spełnione warunki:
(\vec{OA}\times\vec{OX})&gt;=0\ \wedge\  (\vec{OX}\times\vec{OB})&gt;=0
W przeciwnym wypadku (więcej niż pełny półokrąg) sprawdzamy warunek:
(\vec{OA}\times\vec{OX})&gt;=0\ \vee\  (\vec{OX}\times\vec{OB})&gt;=0


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
_13th_Dragon
Nie potrzebne żadne dodatkowe warunki, tak a propos to jest matematyczny zapis tego co ja podałem.
E1
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:17
0

Druga metoda faktycznie też działa (PRAWIE). Czy waszym zdaniem taki przypadek powinien również działać ?
4e0ec0607f.png

MarekR22
no ale ten przypadek jest chyba tak prosty i nieciekawy, że nie warto nad nim się rozpisywać.
E1
no ale jeśli ktoś kolejny raz pisze, że nie potrzeba ŻADNYCH DODATKOWYCH WARUNKÓW to wkleiłem taki obrazek
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Przecież nie ma kolizji.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Shalom
jest bo chodzi cały czas o kolizję z kołem a nie z okręgiem :P
E1
co specjalnie podkreśliłem dużymi literami w 1 wpisie
0

Nie ma tu nic do roboty.

Obliczasz punkty przecięcia okręgów.
Jeśli nie ma to end.

Gdy jest jakiś punkt przecięcia, wtedy sprawdzasz dodatkowo, czy leży na tym łuku... no i to wszystko.
Łuk reprezentujemy w postaci: punktu środkowy, oraz dwa kąty: start i end, od 0 do 2pi każdy.

Shalom
co też proponowałem juz jakiś czas temu ;)
E1
ale to jest kolizja łuku z KOŁEM ! jak mały łuczek leży wewnątrz koła to też mamy kolizje chociaż punkt przecięcia nie leży na łuku !
Shalom
@etet100 ale taki marginalny przypadek możesz sprawdzić dużo prościej, osobnym warunkiem który sprawdza czy odległość między środkami nie jest mniejsza od |r1-r2| -> jak jest to przecięcie, a jak nie ma to przecinasz okręgi.
bogdans
@etet100, napisałeś, że koło i łuk mają identyczny promień. Zamieszczony wyżej rysunek nie ma nic wspólnego z zadaniem.
E1
No chyba jednak nie macie racji. Po pierwsze te promienie są IDENTYCZNE. Po drugie odleglosc miedzy środkami może być od 0 do 2*promień (chociaż to chyba lekkie uproszczenie ale "środek łuku" może być zarówno wewnątrz jak i na zewnątrz koła)
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

@etet100 Jeśli odległość między środkami < |r1-r2| to jedno koło zawiera się w drugim, jeśli jest >= to znaczy że musisz sprawdzić czy okręgi się przecinają - czy odległość między środkami jest mniejsza od sumy promieni. Jeśli nie jest to nie ma przecięć. Jeśli jest to liczysz przecięcia a potem sprawdzasz kąty.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
SI
  • Rejestracja:prawie 14 lat
  • Ostatnio:około 8 godzin
0

Mamy 3 punkty łuku, sprawdzamy ile z nich jest wewnątrz okręgu: jak 3 to koliduje z kołem, jak jeden lub dwa to z kołem i okręgiem, a jak żaden to z niczym.

Shalom
O RLY? Dla ciebie wycinek okręgu to to samo co trójkąt chyba ;] Wyobraź sobie jednak że łuki są wypukłe! Może być tak że punkty łuku nie leżą wewnątrz koła a jednak sam łuk to koło przecina...
0

Wyznaczasz punkty X1, X2 przeciecia się okręgu z kołem. Przynajmniej jeden z tych punktów musi należeć do łuku okręgu. Za punkty A i B przyjmijmy punkty krańcowe okręgu.
Warunek: Bx >= X1x >= Ax, By >= X1y >= Ay. To samo z punktem X2. Warunki nie zadziałają, kiedy całość łuku należy do koła. Bardzo łatwo to sprawdzic - sprawdzasz, czy jeden z punktow kracowych leży wewnetrz koła.

szopenfx
  • Rejestracja:prawie 21 lat
  • Ostatnio:4 miesiące
0

Takie proste zadanie wydawać by się mogło a tyle problemów :P w sam raz na jakąś olimpiadę.

1

To tylko opłakane skutki drastycznie niskiego poziomu nauczania - zero wiedzy z podstaw matematyki.

E1
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:17
0

Przed wojną to był poziom ! Nie to co teraz

0

Na pewno był wyższy, bo musieli wszystko samodzielnie obliczać.

Sopelek
  • Rejestracja:prawie 13 lat
  • Ostatnio:ponad 8 lat
  • Lokalizacja:Kraków
  • Postów:467
0

Moja koncepcja.

  1. Jeśli co najmniej jeden z punktów granicznych łuku (nie wiem jak to się fachowo nazywa, chodzi mi o jego 'zakończenia') zawiera się w kole to kolizja występuje.
  2. Przyjmujemy łuk o promieniu r jako koło o promienu r i sprawdzamy, czy przecina sie z drugim.
  3. Jeśli nie, to kolizji nie ma.
  4. Jeśli tak to wyliczamy punkty przecięcia się tych kół.
  5. Wyliczamy kąt od środka łuku do tych punktów i jeśli co najmniej jeden z tych kątów zawiera się w kącie łuku to kolizja występuje.

teraz jak tak patrze to coś podobnego chyba gdfhjkl napisał.

edytowany 1x, ostatnio: Sopelek
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)