• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Planowanie algorytmu, pomoc matematyczna.

VPS Starter Arubacloud
0 głosów
461 wizyt
pytanie zadane 13 lipca 2019 w Matematyka, fizyka, logika przez Jakub 0 Pasjonat (23,120 p.)
zamknięte 15 lipca 2019 przez Jakub 0

Witam, mam zamiar napisać algorytm generujący Krzywą Kocha. Mam tu małe pytanie matematyczne:

Jeśli chcę znaleźć współrzędne wierzchołka trójkąta równobocznego o znanej długości boków to mogę zrobić to tak:

oczywiście sposobów jest wiele. Ten sposób zadziała jednak tylko wtedy kiedy trójkąt będzie w takiej pozycji ( a nie gdy będzie obrócony o jakiś kąt oraz przeniesiony na dowolne miejsce w przestrzeni ). Jak poradzić sobie z tą drugą kwestią?

Pytanie przedstawie może tak:

Znając współrzędne dwóch wierzchołków trójkąta równobocznego o długości boków d, wylicz współrzędne trzeciego niewiadomego wierzchołka.

Wiem że pytanie może być mylące bo nie do końca wiadomo o jaki kąt obrócony jest trójkąt i "czy postawić współrzędne tego wierzchołka za czy przed odcinkiem tworzącym znaną podstawę figury"...  Myślę więc że ważna jest kwestia o jaki kąt jest obrócony trójkąt. I tego też nie jestem pewny jak wyliczyć :/

jak widać na powyższym obrazku punkty wierzchołków określamy na odcinkach o różnych nachyleniach. Intuicyjnie wydaje mi się że wszystkie odcinki w dalszych procesach iteracji są nachylone 60 lub 120 stopi względem odcinka |AB|.

Jeśli to jest prawda to z problemem umiem sobie poradzić a jeśli nie to jak wyliczyć wierzchołki ( górne ) każdego z tych pół "trójkątów"?

 

Wiem że są to podstawy matmy, ale "głupi jest się tylko raz...". Będę więc bardzo wdzięczny za pomoc :)

komentarz zamknięcia: problem rozwiązany
komentarz 13 lipca 2019 przez DragonCoder Nałogowiec (36,500 p.)
edycja 13 lipca 2019 przez DragonCoder
Skoro dlugosc boku jest taka sama, to odstep między wuerzcholkami musi byc takisam. Czyli A (9/5) i B (2/1) to mozesz odjac od siebie te wartosci, przez co uzyskasz odstep miedzy tymi punktami. Pozniej ta roznice dodajesz i otrzymujesz 3 wierzcholek, jezeli nic nie zapomnialem to powinno zadzialac. Nie mam kartki, zeby rozrysowac i sprawdzic, wiec robie rysunek w glowie. Ale wyprobuj isprawdz czy sie sprawdza.

2 odpowiedzi

0 głosów
odpowiedź 13 lipca 2019 przez niezalogowany
wybrane 15 lipca 2019 przez Jakub 0
 
Najlepsza

Okej zacznij od trójkąta. Przy kolejnych iteracjach każdy odcinek zostanie zamieniony na kolejne cztery odcinki. 

Krzywa Kocha powstaje z odcinka, poprzez podzielenie go na 3 części i zastąpienie środkowej ząbkiem (o ramieniu długości równej 1/3 odcinka) takim, że wraz z usuwaną częścią tworzy trójkąt równoboczny. Krok ten jest powtarzany w nieskończoność, dla każdego fragmentu odcinka.

Dla każdego odcinka możesz policzyć wektor zaczepiony D. Podziel go przez trzy (dzielenie przez skalar). Teraz możesz obliczyć punkty podstawy trójkąta (dodawanie wektorów). Obróć wektoro 60 stopni i oblicz brakujący wierzchołek. Jeżeli będziesz cyklicznie wstawiał punkty to wszystko powinno wyjść dobrze. Oczywiście wierzchołek możesz go obliczyć również z wysokości.

komentarz 13 lipca 2019 przez Jakub 0 Pasjonat (23,120 p.)

Dziękuje za odpowiedź, mówiąc szczerzę to dawno nie miałem takiego problemu z matematyką, napisałem taki kod:

std::vector<sf::Vertex> tri{
		{ sf::Vector2f{500.f, 200.f}, sf::Color{ 203, 20, 66, 255 } },
		{ sf::Vector2f{0, 0}, sf::Color{ 203, 20, 66, 255 } }, // do odgadnięcia 
		{ sf::Vector2f{1000.f, 400.f}, sf::Color{ 203, 20, 66, 255 } }
	};

	auto f = [](sf::Vector2f vec1, sf::Vector2f vec2) {return std::sqrt(std::pow(vec1.x - vec2.x, 2) +													  std::pow(vec1.y - vec2.y, 2)); };

	float length = f(tri[0].position, tri[2].position); // długość odcinka 
	float angle = std::atan2f(tri[0].position.x - tri[2].position.x, tri[0].position.y - tri[2].position.y);
	// kąt nachwylenia odcinka

	tri[1].position.x = std::cos(angle + 60.f * (3.14f / 180.f)) * length + tri[0].position.x;
	tri[1].position.y = std::sin(angle + 60.f * (3.14f / 180.f)) * length + tri[0].position.y;

To nie jest na razie generacja fraktala, a po prostu odgadnięcie trzeciego wierzchołka trójkąta. Nie mam żadnego problemu z odgadnięciem tych współrzędnych gdy znany odcinek jest na poziomej płaszczyźnie. Gorzej w przypadku jego rotacji. Za pomocą funkcji atan planowałem określić tą rotacje ( kąt ) odcinka zbudowanego z dwóch znajomych wierzchołków, następnie dodać ten kąt do 60 stopni.

Nic jednak z tego nie wychodzi, funkcja atan opiera się na innej mierze kątów od -180 do 180 a kąty w SFML są od 0 do 360.

Jestem kompletnie przybity :( Myślę dzisiaj nad tym kilka godzin, denerwuje się... wiem że to nie jest trudny problem a ja z matmy nie jestem w szkole najgorszy. Po prostu nie wiem co się dzieje z moim myśleniem :/ Mam nadzieje że to tylko przez zmęczenie.

1
komentarz 13 lipca 2019 przez niezalogowany

Skorzystaj ze wzorów na obrót wektora (równanie 2). Na kątach to będzie zbyt problematyczne ;) Oczyścić umysł i podejdź później do tego. W razie problemów możesz wstawić cały kod i spróbuje coś więcej doradzić.

PS. std::hypot - taka ciekawostka ;)

komentarz 14 lipca 2019 przez Jakub 0 Pasjonat (23,120 p.)

Dopiero dziś wieczorem mam czas nad tym pomyśleć i znowu mam pewien problem...

rozumiem że chodzi o ten wzór:

prawda jest taka że jeśli chcę obrócić wektor o pewien kąt to i tak muszę znać jego wcześniejsze "nachylenie" ( alfa ).. To co potrafię wyliczyć to wszystkie boki trójkąta prostokątnego którego przeciwprostokątną jest transformowany wektor. Mam więc taką sytuację:

Skoro da się wyliczyć sinus jakiegoś kąta podstawiając go po prostu do funkcji to powinna być też możliwa odwrotna sytuacja, potrzebuję dowiedzieć się jaką miarę ma kąt alfa na podstawie wartości jego sinusa...

czyli mam takie równanie:

sin(nieznany alfa) = znana wartość

nieznany alfa = ?

Nie mogę w ogóle znaleźć w internecie na ten temat informacji, wszędzie tylko pisze że trzeba sięgać do tabelek...

Sorki że zawracam głowę ale w końcu do czegoś może dojdę :)

 

komentarz 14 lipca 2019 przez niezalogowany
edycja 14 lipca 2019

czyli mam takie równanie:

sin(nieznany alfa) = znana wartość

nieznany alfa = ?

Wynik tego działania to nieznany kąt = arcsin(znana wartość) - funkcja cyklometryczna (w C++ std::asin).

prawda jest taka że jeśli chcę obrócić wektor o pewien kąt to i tak muszę znać jego wcześniejsze "nachylenie" ( alfa ).. 

Wcale nie musisz znać alfy. Masz już gotowy wzór na wektor przesunięcia zależny od jednego kąta, o który obrócisz wektor. Możesz podstawić tam od razu kąt 60 stopni.

komentarz 15 lipca 2019 przez Jakub 0 Pasjonat (23,120 p.)

Rzeczywiście... myślałem początkowo że kąt alfa odnosi się we wzorze do czegoś innego.

Ważne jest to że wreszcie mi się udało... Wykorzystałem to równanie:



już miałem się poddać aż w końcu zobaczyłem na ekranie ten "piękny" trójkąt prostokątny ;)

chyba muszę się bardziej zainteresować matmą żeby samemu wyprowadzać wzory, bo szukanie w internecie w masie stron i forów pasujących do sytuacji gotowych obliczeń jest dość wyczerpujące.

komentarz 15 lipca 2019 przez niezalogowany
O ten wzór był nawet w linku, który Ci podrzuciłem tylko w trochę trudniejszym zapisie z macierzą. Poucz się o działaniach na wektorach - bardzo przydadzą się w wielu projektach ;)
+1 głos
odpowiedź 13 lipca 2019 przez Chess Szeryf (76,710 p.)
edycja 13 lipca 2019 przez Chess

link link Wyliczanie trzeciego wierzchołka.

A=(1,2) B=(5,2)

|AB| = sqr_root((xB-xA)^2+(yB-yA)^2)

|AB| = sqr_root((5-1)^2+(2-2)^2)

|AB| = 4^2+0^2

|AB| = 4

C=(x,y) Stąd wynika, że x=3, bo od zera do pięciu jest sześć jednostek i powoła z tego wynosi 3.

C=(3,y)

|AC|^2=(x-1)^2+(y-2)^2

|BC|^2=(x-5)^2+(y-2)^2

|AC|=|BC|

|AC|^2=(3-1)^2+(y-2)^2

4^2=2^2+y^2-4y+4

y^2-4y-8=0

a=1 b=-4 c=-8

/\=b^2-4ac

/\=16+32=48

sqr_root(/\)=4(sqr_root(3))

y1=(4-4(sqr_root(3)))2 y2=(4+4(sqr_root(3)))/2

y1=2-2(sqr_root(3)) y2=2+2(sqr_root(3))

C=(3;2-2(sqr_root(3))) lub (3;2+2(sqr_root(3)))

sqr_root - pierwiastek kwadratowy
^ - podniesienie do potęgi
/\ - delta

Tym wzorem obliczysz obrót punktu w układzie współrzędnych.

x' = x * cos(alpha) - y * sin(alpha)

y' = x * sin(alpha) + y * cos(alpha)

alpha - znak alfa

Wzorowałem się na tych pierwszych dwóch link'ach.

Podobne pytania

0 głosów
1 odpowiedź 603 wizyt
0 głosów
2 odpowiedzi 295 wizyt
pytanie zadane 20 kwietnia 2020 w Matematyka, fizyka, logika przez Aisekai Nałogowiec (42,190 p.)
+1 głos
1 odpowiedź 361 wizyt

92,453 zapytań

141,262 odpowiedzi

319,086 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...