Początki c++, Obliczyć długość krzywej wyrażonej zależnościa

0

Cześć, juz na pierwszych możliwych zajęciach mimo, że mało kto miał wcześniej rozszerzona informatykę i programowanie czy matematykę dostaliśmy zadania do wykonania.

Opracować algorytm, napisać, uruchomić i przetestować program

Oblicz długość krzywej wyrażonej zależnością:
y=x^2 - sin(x) - 1
w danym przedziale (a,b) z dokładnością do ε.

wskazówka: zastąpić krzywą przez łamaną i sukcesywnie zwiększać liczbę przedziałów wyznaczających odcinki do czasu, gdy kolejna zmiana długości łamanej stanie się mniejsza od ε.

głownie chodzi mi o pomoc z opracowaniem algorytmu i wyjaśnienie co i jak, programowanie w c++ już sam postaram się zrobić

1

Niezbyt rozumiem co nie jasne?

  1. piszesz: f(x) = x^2 - sin(x) - 1
  2. obliczasz odległość od f(a) do f(b) Pitagorasem: pit(f(a),f(b)) oznaczasz jako previouse.
  3. Następnie dzielisz przedział przez dwa i obliczasz pit(f(a),f((a+b)/2))+pit(f((a+b)/2),f(b)) oznaczasz jako current
  4. Jeżeli previouse-current < ε to koniec, wynik to current
  5. W przeciwnym wypadku previouse=current, dzielimy przedział jeszcze na 2 i kontynuujemy od pkt 3.
1

Tak to wygląda:

#include <cmath>
#include <iostream>
using namespace std;

double f(double x) {
	return x * x - sin(x) - 1;
}

double dist(double x0, double y0, double x1, double y1) {
	return sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2));
}

double sumDist(double a, double b, int n) {
	double s = 0;
	double step = (b - a) / n;
	for (int i = 0; i < n; ++i) {
		s += dist(a, f(a), a + step, f(a + step));
		a += step;
	}
	return s;
}

void curveLength(double a, double b, double e) {
	int n = 1;
	double len = 0;
	double lenStart = sumDist(a, b, n);
	while (1) {
		len = sumDist(a, b, ++n);
		if (len - lenStart < e) {
			cout << "Lenght is: " << len;
			break;
		}
		else {
			lenStart = len;
		}
	}
	
}

int main(int argc, char **argv){
	curveLength(0, 10, 0.00000001D); // -> 102.17
	cout << "\n";
	return 0;
}

Dla potwierdzenia wolframalpha: https://www.wolframalpha.com/input/?i=curve+length&assumption=%7B%22F%22%2C+%22ArcLength%22%2C+%22curve%22%7D+-%3E%22x+*+x+-+sin%28x%29+-+1%22&assumption=%7B%22F%22%2C+%22ArcLength%22%2C+%22a%22%7D+-%3E%220%22&assumption=%7B%22C%22%2C+%22curve+length%22%7D+-%3E+%7B%22Formula%22%7D&assumption=%7B%22F%22%2C+%22ArcLength%22%2C+%22b%22%7D+-%3E%2210%22
Chyba w miarę oczywiste, kluczowe funkcje sumDist i curveLength iteracyjnie liczą, co mają liczyć:), sumDist zwraca długość krzywej w zależności od długości łamanych przedziałów na które ją rozbija, a curveLength sukcesywnie zwiększa dokładność [tej łamanej] i jak ta wejdzie poniżej epsilona, to drukuje wynik. Możesz to jeszcze poprawić ograniczjąc ilość iteracji, gdy nie da się osiągnąć zadanej dokladności, zamiast tego while (1).

0
lion137 napisał(a):

W komentarzu hej uważam, że sobie nie poradzisz kompilatorze, ja wiem lepiej

Nawet jak na 100% jesteś pewien że kompilator to zoptymalizuje ...
Po pierwsze - a inny kompilator też zoptymalizuje?
Po drugie - jakim prawem kompilator miał by optymalizować: - pow(a,2)? A jak dołączysz inną bibliotekę przed standardową? gdzie pow robi zupełnie coś innego i/lub inaczej?
Po trzecie - nawet jak firma zatrudnia sprzątaczkę to i tak nikt nie stawia kloca pośrodku korytarza, owszem sprzątaczka po tobie posprząta, ale smrodek i tak pozostanie.

0

Jak mam być szczery dalej średnio rozumiem jak i dlaczego. Dlaczego pitagorasem i jak to się ma w programowaniu?

0

"Jak mam być szczery dalej średnio rozumiem jak i dlaczego. Dlaczego pitagorasem i jak to się ma w programowaniu?" Ciężko się odnieść, czego nie Rozumiesz, wskaż konkretne kawałki kodu, "pitagorasem", bo Pitagorasem Liczysz odległość dwóch punktów płaszczyzny.

1
mateusz Karpowicz napisał(a):

Jak mam być szczery dalej średnio rozumiem jak i dlaczego. Dlaczego pitagorasem i jak to się ma w programowaniu?

Ponad 2,5 tyś lat temu Pitagoras https://pl.wikipedia.org/wiki/Pitagoras wymyślił jak obliczyć najkrótszą odleglość pomiędzy dwoma punktami.
Z tym że w tym zadaniu możesz liczyć odległość Manchatańską https://biznes.metodolog.pl/glossary/metryka-miejska-manhattanska/ dla tego algorytmu powinno być bez różnicy.
Ba, będzie znacznie szybciej, lecz mniej dokładnie.

0

Sorki, nie odswieżyłem strony, a skomentowałem :D po przeanalizowaniu tego co napisaliście wszystko zrozumiałem, hula aż miło, teraz tylko schemat blokowy zrobić. Tylko czy ,,i" pełni jakąś funkcje, bo tylko tego nie rozumiem, co ona tutaj robi

1

n przysłane do sumDist ustala na jakimi odcinkami przybliżamy krzywą, a sumowanie już odbywa się w pętli z indeksem i; Zobacz, jak n będzie 1, to step wynosi b - a, czyli najmniej dokładne przybliżenie (początek i koniec krzywej), dalej zwiększając n rozbijamy na coraz więcej kawałków = większa dokładność.

0
lion137 napisał(a):

n przysłane do sumDist ustala na jakimi odcinkami przybliżamy krzywą, a sumowanie już odbywa się w pętli z indeksem i; Zobacz, jak n będzie 1, to step wynosi b - a, czyli najmniej dokładne przybliżenie (początek i koniec krzywej), dalej zwiększając n rozbijamy na coraz więcej kawałków = większa dokładność.

Tak, rozumiem, że curveLength przesyła zwiekszone "n" aby sumdist mogło podzielić na wiecej odcinków, aby obliczyć z większą dokładnością, jednakże to "i" ma jakiś sens poza tym, że musi istnieć jakiś warunek, aby pętla mogła się wykonać? o ile mowie z sensem :D

1

Tak, generalnie tak, sumowanie ma się wykonać n razy, więc pętla jest tak zrobiona, że wykona się n razy. Można też pewnie było zrobić pętlę while, np.:
while (a <= b).

0
lion137 napisał(a):

Tak, generalnie tak, sumowanie ma się wykonać n razy, więc pętla jest tak zrobiona, że wykona się n razy. Można też pewnie było zrobić pętlę while, np.:
while (a <= b).

dzięki wielkie! Czyli dobrze myslałem. Teraz tylko schemat blokowy, o który chodziło mi w sumie na poczatku niż o pełen kod i zrobione :D Dzieki jeszcze raz

0

Jak by to wyglądało rozrysowane jako schemat blokowy, bo skomplikowane trochę te pętle przez przejścia do podprogramów, na pewno pierwsza będzie krótka :D

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