Przecięcie trójkąta z odcinkiem - kolizje 3D

0

Witam, problem jest taki:

Mamy trójkąt i odcinek, które przecinają się lub nie :) Po pierwsze chcę obliczyć czy się przecinają i punkt przecięcia.

I najważniejsze - potrzebuję jeszcze znaleźć wektor, który nazywa się po ang. "penetration depth", czyli najkrótszy możliwy wektor przesunięcia, który wysunie kolidującą linię z trójkąta i ustawi tak, że będzie styczna z trójkątem, ale nie wystąpi przecięcie.

Wiecie, jak takie coś zrobić? Jest może jakaś odpowiednia biblioteka do tego?

0

Pierwsze pytanie:

  1. Piszesz równanie płaszczyzny P zawierającej trójkąt i równanie prostej l zawierającej odcinek.
  2. Szukasz punktów przecięcia P i l:
  • punktów przecięcia nie ma - l i P nie mają punktów wspólnych
  • jest jeden punkt wspólny A, sprawdzasz czy A leży na odcinku i czy A leży w trójkącie
  • jest wiele punktów wspólnych, tzn. trójkąt i odcinek lezą w jednej płaszczyźnie, szukasz punktów
    przecięcia prostej l z prostymi zawierającymi boki trójkąta, co dalej to chyba sam wymyślisz.
    Pozdrawiam

Ze słownika idiomów St. Barańczaka Sto osób z górą. A hundred people, the mountain included.

0

Mozna bezwariantowo policzyc punkty przeciecia prostej zawierajacej odcinej z prostymi zawierajacymi boki trojkata (3 uklady rownan) i za kazdym razem sprawdzac czy znajduja sie na odcinku (3 sprawdzenia).

0

@johny_bravo, czytałeś temat ? Zagadnienie jest trójwymiarowe. Odcinek może przecinać trójkąt nie przecinając boków.

0

O sorki, nie zauwazylem [wstyd]

0

"wypchnąć" odcinek z tego trójkąta, trójkąt jest płaszczyzną na której jest punkt przez który przechodzi prosta ( o ile przechodzi )

budujesz trzy trójkąty dla każdego boku trójkąta, jako wierzchołek dajesz każdemu punk przecięcia, dla każdego wyliczasz najkrótszą odległość od podstawy ( bok trójkąta ) czyli wysokość, wybierasz najkrótsza wysokość, i przestawiasz tak prostą by przechodziła przez koniec wysokości leżący na podstawie

napisałem zrozumiale? =]

0

@up, nie wiem czy piszesz zrozumiale, ale chyba nie masz racji. Jeżeli punkt S jest punktem przecięcia prostej z trójkątem, a R jest punktem na obwodzie trójkąta leżącym najbliżej punktu S to rozumiem, że proponujesz przesunięcie o wektor PS. To na ogół nie jest najkrótszy wektor, jeżeli rzut prostopadły wyjściowej prostej na płaszczyznę trójkąta pokrywa się z prostą RS, to starczy przesuwać o wektor prostopadły do wyjściowej prostej, którego rzut na płaszczyznę trójkąta ma kierunek prostej RS. Mam nadzieję, że napisałem zrozumiale.

W środku pampy śpiewał gaucho Bruno:
"Dźwięcz gitary mej miłosna struno!
Podnieca mnie i dama,
I pastuch kawał chama,
Ale lama to numero uno!"

0
  1. sprawdzasz czy wektor ruchu (promienia) jest rownolegly do plaszyzny z ktora koliduje czy ja przecina, jak przecina to liczysz z rownania plaszczyzny punkt przeciecia (3D)
  2. sprawdzasz znaki iloczynow wektorowych liczonych z wektorow stworzonych pomiedzy wierzcholkami a punktem przeciecia plaszyzny na ktorej ow trojkat lezy sa takie same (macierze, elementarne mnozenia i dodawaniia), jezeli sa takie same punkt przeciecia jest w trojkacie jezeli nie wektor nie przecina trujkata :P

poszukaj troche o raytracingu, to oco pytasz to elementarne podstawy :P

0

@bogdan

tylko taki sposób wymyśliłem =D
jeśli prosta nie będzie na tej samej płaszczyźnie co trójkąt to chyba to co wybredziłem by zadziałało?

0

@cepa, co to jest trujkąt ?
@up, masz dwie osobowości ?
Chyba nie. Załóżmy, że trójkąt jest równoboczny, prosta przechodzi przez jego środek S, leży nad jedną z wysokości i nie jest do trójkąta prostopadła. R niech oznacza spodek tej wysokości. O ile dobrze zrozumiałem proponujesz przesunięcie o wektor SR. Jestem pewien, że można przesuwać prostą również o wektor AR (krótszy od SR), punkt A jest rzutem prostopadłym punktu R na wyjściową prostą.

0
bogdans napisał(a)

@cepa, co to jest trujkąt ?

mialem na mysli trujkont oczywiscie ;-)

0

tej osobowości używam gdy nie chce mi się logować =]

a tego drugiego wektora to zbytnio nie rozumiem bo jakoś jeszcze nie brałem nic o wektorach w 3D, ale z tego co zrozumiałem to ty nie chcesz przesuwać punktu przecięcia na brzeg tylko całą prostą w 3D wysunąć poza trójkąt ?

0

A jest istotna różnica między wektorami 2D a 3D ? 3D winien być łatwiejsze do zrozumienia bo żyjemy w świecie 3D.
Takie było pytanie

wektor przesunięcia, który wysunie kolidującą linię z trójkąta

0

jak działa wektor 3D to oczywiście rozumiem =D ale z rozumieniem jak ty je tam robisz to nie za bardzo ( wesprę się fachową lekturą więc do jutra powinienem już rozumieć )

0

Nie literatura fachowa jest potrzebna ale trochę wyobraźni przestrzennej. Dla uproszczenia zastąpię trójkąt kołem o promieniu r, prosta przechodzi przez środek koła. Jeśli prosta jest prostopadła do koła, to trzeba ją przesunąć o wektor o długości r - kierunek jest obojętny. Jeśli prosta tworzy z płaszczyzną koła kąt alfa, to wystarczy przesunąć o wektor o długości r*sin(alfa).

0
bogdans napisał(a)

Nie literatura fachowa jest potrzebna ale trochę wyobraźni przestrzennej. Dla uproszczenia zastąpię trójkąt kołem o promieniu r, prosta przechodzi przez środek koła. Jeśli prosta jest prostopadła do koła, to trzeba ją przesunąć o wektor o długości r - kierunek jest obojętny. Jeśli prosta tworzy z płaszczyzną koła kąt alfa, to wystarczy przesunąć o wektor o długości r*sin(alfa).

pozno jest i rozumienie u mnie lezy ale Ty chcesz przesowac prosta o wektor aby wykrywac kolizje z kula!?
imho jak jest kulka i prosta to ma 0 1 lub 2 punkty w spolne a ich policzenie jest banalne :P

0

@potwor_ proponował by znaleźć punkt R na obwodzie trójkąta, który leży najbliżej punktu S:= punkt przecięcia trójkąta i odcinka, a potem przesuwać prostą o wektor SR. Wektor SR jest oczywiście najkrótszym (jednym z najkrótszych) wektorem leżącym w płaszczyźnie trójkąta przesuwającym wyjściową prostą we właściwe położenie. Ja się starałem pokazać, że istnieją krótsze wektory - nie leżące w płaszczyźnie trójkąta - też robiące co trzeba.

0

umh... gdyby tak położyć ten trójkąt "płasko" to ten twój wektor wyciągnie prostą w górę lub w dół, ewentualnie w bok ?

0
bogdans napisał(a)

Nie literatura fachowa jest potrzebna ale trochę wyobraźni przestrzennej.

Ja sie zgadzam ale sa co wola to trzeba im dac

http://graphics.stanford.edu/courses/cs348b-98/gg/intersect.html

0

Jeden rysunek (nawet kiepski) więcej wart niż tysiąc słów.

user image

0

Nie wszystko zrozumiałe :)

Samą kolizję jeszcze kapuję, ale główny problem, to właśnie to wysunięcie.
A gdyby policzyć, który z wektorów przesunięcia (zaczepionych w punkcie przecięcia S) jest najkrótszy spośród czterech: w kierunku prostopadłym do płaszczyzny trójkąta czy 1 z 3 prostopadłych do którejś krawędzi trójkąta. Zależy mi przede wszystkim na prędkości obliczania. Z tym i tak jest sporo liczenia niestety.

0

To będzie bardzo niedokładne. Wyobraź sobie trójkąt równoboczny o boku i odcinek o długości l, którego środek leży w środku trójkąta. Ponadto odcinek leży nad wysokością trójkąta i tworzy z wysokością kąt alfa Ze względu na symetrię wszystkie odcinki prostopadłe do boków trójkąta maja taka samą długość
(= asqrt(3)/6), odcinek prostopadły do płaszczyzny trójkąta przesuwający odcinek tak by jego koniec leżał w płaszczyźnie trójkąta ma długość z=lsin(alfa)/2 (po takim przesunięciu odcinek może być rozłączny z trójkątem). A wystarczy przesunąć o wektor prostopadły do odcinka o długości a*sqrt(3)*sin(alfa)/6.
Prawdopodobnie trzeba wyznaczyć odległości prostej zawierającej odcinek od prostych zawierających boki trójkąta i wziąć najmniejszą z nich. Poszukaj w książkach z geometrii analitycznej.
Odległość dwóch prostych, m i n to najmniejsza odległość dwóch punktów z których jeden leży na m, drugi na n.

0

Gry 3D, Kolizja Sferyczna [funkcja intersectedpolygon]

lub punk przeciecia odcinek plaszczyzna, masz wierzcholki trojakata i masz jego boki sprawdzasz po ktorej stronie znajduje sie punkt przeciecia jak po tej samej stornie dla wszystkich bokow to punkt przeciecia znajduje sie w trojkacie (pamietajac o takiej jednej zasadzie.....)

function PUNKT_PRZECIECIA_ODCINEK_PLASZCZYZNA(vNormal : t3dpoint;
pointonplane : t3dpoint;
 vLine : array of t3dpoint):t3dpoint;
const
  MATCH_FACTOR : Extended = 0.9999999999;
var

  vIntersection : t3dpoint;
  originDistance : Extended;
  distance1 : Extended;
  distance2 : Extended;
  m_magnitude : Double;
  vPoint : t3dpoint;
  vLineDir : t3dpoint;
  Numerator : Extended;
  Denominator : Extended;
  dist : Extended;
  Angle,tempangle : Extended;
	vA, vB : t3dpoint;
  I : integer;
  dotProduct : Extended;
  vectorsMagnitude : Extended;
begin


	originDistance := 0;
  distance1 := 0;
  distance2 := 0;
  vPoint.X := 0;
  vPoint.Y := 0;
  vPoint.Z := 0;

  vLineDir.X := 0;
  vLineDir.Y := 0;
  vLineDir.Z := 0;

	Numerator := 0.0;
  Denominator := 0.0;
  dist := 0.0;
  Angle := 0.0;



  originDistance := -1 * ((vNormal.x * pointonplane.x) +
                          (vNormal.y * pointonplane.y) +
                          (vNormal.z * pointonplane.z));


	distance1 := ((vNormal.x * vLine[0].x)  +
		         (vNormal.y * vLine[0].y)  +
				 (vNormal.z * vLine[0].z)) + originDistance;

	distance2 := ((vNormal.x * vLine[1].x)  +
		         (vNormal.y * vLine[1].y)  +
				 (vNormal.z * vLine[1].z)) + originDistance;

	if(distance1 * distance2 >= 0) then
  begin


    exit;
  end;



  vLineDir.x := vLine[1].x - vLine[0].x;
	vLineDir.y := vLine[1].y - vLine[0].y;
	vLineDir.z := vLine[1].z - vLine[0].z;

  m_magnitude := sqrt((vLineDir.x * vLineDir.x) +
                      (vLineDir.y * vLineDir.y) +
                      (vLineDir.z * vLineDir.z) );


	vLineDir.x := vLineDir.x/m_magnitude;
	vLineDir.y := vLineDir.y/m_magnitude;
	vLineDir.z := vLineDir.z/m_magnitude;



	Numerator := -1 * (vNormal.x * vLine[0].x +
          				   vNormal.y * vLine[0].y +
				             vNormal.z * vLine[0].z + originDistance);




	Denominator := ( (vNormal.x * vLineDir.x) + (vNormal.y * vLineDir.y) + (vNormal.z * vLineDir.z) );

	if( Denominator = 0.0) then
  begin
		vIntersection := vLine[0];
  end
  else
  begin


  	dist := Numerator / Denominator;



  	vPoint.x := (vLine[0].x + (vLineDir.x * dist));
  	vPoint.y := (vLine[0].y + (vLineDir.y * dist));
  	vPoint.z := (vLine[0].z + (vLineDir.z * dist));

  	result.x := vPoint.x;								// Return the intersection point
    	result.y := vPoint.y;
          	result.z := vPoint.z;

  end;



end;

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