[Algorytmy] Algorytm rysowania łamanej, odległej od innej o y

MichalProg
Użytkownik
Użytkownik
Posty: 411
Rejestracja: 28 cze 2011, o 21:11
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 62 razy
Pomógł: 1 raz

[Algorytmy] Algorytm rysowania łamanej, odległej od innej o y

Post autor: MichalProg »

Dzień dobry.

Napisałem algorytm rysujący łamaną i klonujący ją, przesuwając o \(\displaystyle{ y}\) w pionie do dołu

Kod: Zaznacz cały

https://www.youtube.com/watch?v=vQc8Oh01dF8


Potrzebuję napisać podobny algorytm, tylko rysujący łamaną oddaloną (o ile to możliwe) o \(\displaystyle{ y}\).

Proszę o pomoc w tym procesie :(
Ostatnio zmieniony 14 gru 2021, o 17:56 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
a4karo
Użytkownik
Użytkownik
Posty: 22153
Rejestracja: 15 maja 2011, o 20:55
Płeć: Mężczyzna
Lokalizacja: Bydgoszcz
Podziękował: 38 razy
Pomógł: 3748 razy

Re: Algorytm rysowania łamanej, odległej od innej o y

Post autor: a4karo »

Zbiór punktów oddalonych od łamanej o ustaloną liczbę na ogół nie jest łamaną. W wierzchołkach łamanej pojawią sie łuki okręgów.
MichalProg
Użytkownik
Użytkownik
Posty: 411
Rejestracja: 28 cze 2011, o 21:11
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 62 razy
Pomógł: 1 raz

Re: Algorytm rysowania łamanej, odległej od innej o y

Post autor: MichalProg »

Aha ok. Mój problem polega na tym, że chcę napisać funkcję, która będzie badać, czy może zagłębić się w dany fragment wykresu. Jak np. fragment jest zbyt "wąski" i kopia wykresu się nie zmieści, to rysuje prostą poniżej zagłębienia. Ale mam problem i od kilku dni jestem w kropce. A może po prostu badać ilość przecięć wykresu z nim samym i jak jest powyżej 1 w danym fragmencie, to obcinać ten fragment?

Dodano po 1 godzinie 43 minutach 4 sekundach:
Jakbym np. miał łamaną na zasadzie:

Kod: Zaznacz cały

_|^|_
I przerwa między pionowymi partiami byłaby zbyt wąska, to jak odtworzyć ostatni poprawny fragment wykresu i ominąć niepoprawny, tj:

Kod: Zaznacz cały

_|^|_
_____
Dodano po 14 godzinach 57 minutach 42 sekundach:
OK. Mam kod funkcji, która znajduje punkty. Tylko problem z odpowiednim dobraniem odległości (czasem musi być + a czasem -)

Kod: Zaznacz cały

function findNextPoint(pA1, pA2, pB1, pB2, shift) {
    var line1 = setLineFrom2Points(getPointX(pA1), getPointY(pA1), getPointX(pA2), getPointY(pA2));
    var line2 = setLineFrom2Points(getPointX(pB1), getPointY(pB1), getPointX(pB2), getPointY(pB2));
    var p = getCommonLineCrossPoint(line1, line2);

    // dostosować shifty
    var line1_0 = getLine0(line1, p, shift);
    var line2_0 = getLine0(line2, p, shift);

    return getCommonLineCrossPoint(line1_0, line2_0);
}
Teraz muszę uściślić, kiedy \(\displaystyle{ shift}\) ma być z + a kiedy -, na podstawie linii lub punktów. Pomożecie? :)

Kod: Zaznacz cały

function test() {
    var A1 = setPoint(10, 10);
    var A2 = setPoint(20, 10);

    var B1 = setPoint(20, 10);
    var B2 = setPoint(20, 20);

    console.log(findNextPoint(A1, A2, B1, B2, 5));
}
To daje w wyniku:

Kod: Zaznacz cały

{x: 25, y: 15}
A powinno:

Kod: Zaznacz cały

{x: 15, y: 15}
Ponury123
Użytkownik
Użytkownik
Posty: 128
Rejestracja: 5 lip 2015, o 14:48
Płeć: Mężczyzna
Lokalizacja: nie wiem
Podziękował: 11 razy
Pomógł: 24 razy

Re: Algorytm rysowania łamanej, odległej od innej o y

Post autor: Ponury123 »

Możesz zrobić dla shifta dodatniego i ujemnego i sprawdzić która wersja nie przecina się z line1 i line2.
kubadt
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 28 gru 2017, o 19:56
Płeć: Mężczyzna
Lokalizacja: Polska
Pomógł: 1 raz

Re: Algorytm rysowania łamanej, odległej od innej o y

Post autor: kubadt »

Nie rozumiem, dlaczego

\(\displaystyle{ g(f(x), y_0, y_1) = \begin{cases} f(x)-y_1 \Leftrightarrow f(x)-y_1 < y_0 \\ y_0 \Leftrightarrow f(x) - y_1 \ge y_0 \end{cases} }\)

miałoby tutaj nie zadziałać.

Innymi słowy, w postaci algorytmu
  • 1. Dla każdego punktu x na osi odciętych w rysowanej przestrzeni
    • 1.a Oblicz y = f(x) - y_1
      1.b Jeżeli y > y_0
      • 1.b.i Narysuj punkt o współrzędnych (x, f(x)-y_1)
      1.c W przeciwnym wypadku
      • 1.c.i Narysuj punkt (x, y_0)
W różnych językach programowania implementacja będzie wyglądała inaczej. W pythonie na przykład może to wyglądać tak:

Kod: Zaznacz cały

from matplotlib import pyplot as plt
import numpy as np
def f(x):
    return np.where(np.sin(x)>0,x/(2*np.pi)-np.ceil(x/(2*np.pi)),-x/(2*np.pi)-np.ceil(-x/(2*np.pi)))
def f2(x, y_0, y_1):
    return np.where((f(x) - y_1) < y_0, y_0, f(x)-y_1)
x = np.linspace(-10,10,1000)

plt.plot(x,f(x))
for i in range(10):
    y_1 = i/10
    plt.plot(x,f2(x,-1.4,y_1))

Jeżeli nie chodzi o to, to musisz lepiej sformułować problem, aktualne jego przedstawienie nie jest jasne.
MichalProg
Użytkownik
Użytkownik
Posty: 411
Rejestracja: 28 cze 2011, o 21:11
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 62 razy
Pomógł: 1 raz

Re: Algorytm rysowania łamanej, odległej od innej o y

Post autor: MichalProg »

To, co napisałeś, mam już zrobione. Moje pytanie tyczyło się innego zagadnienia. Bo tutaj masz przesunięcie bezwzględne w y (o stałą odległość, jak na filmie)

A ja próbuję uzyskać stałe przesunięcie wykresów od siebie.

Kod: Zaznacz cały

function findNextPoint(pA1, pA2, pA3, shift) {
    var line1 = setLineFrom2Points(getPointX(pA1), getPointY(pA1), getPointX(pA2), getPointY(pA2));
    var line2 = setLineFrom2Points(getPointX(pA2), getPointY(pA2), getPointX(pA3), getPointY(pA3));
    var p = getCommonLineCrossPoint(line1, line2);
    var ang1 = getLineA(line1);
    var ang2 = getLineA(line2);
    
    if (isPtEqual(pA1, pA2) || isPtEqual(pA2, pA3) || isPtEqual(pA1, pA3))
        return setPoint(Infinity, Infinity);

    if (isNaN(getPointX(p)))
        return getPointShift(line1, pA2, (ang1 >= 0) ? shift : -shift);

    
    var line1_0 = getLine0(line1, p, (ang1 >= 0) ? shift : -shift);
    var line2_0 = getLine0(line2, p, (ang2 >= 0) ? shift : -shift);

    return getCommonLineCrossPoint(line1_0, line2_0);
}
Tylko niestety nie działa tak jak chciałem :(

Kod: Zaznacz cały

function getPointXYOnLineShift(line, p, shift) {
    if (!checkIfPointOnLine(line, p))
        throw "error";

    // serve shift (+- cos sin)
    var angle = getLineAngle(line);
    var x = ((angle < 0) ? Math.cos(angle) : -Math.cos(angle));
    var y = Math.sin(angle);

    console.log(x, y);

    return setPoint(getLineX(p) + shift * ((getLineX(line) != Infinity) ? 0 : Math.cos(getLineA(line))), getPointY(p) + shift * ((getLineX(line) != Infinity) ? 1 : y));
}
Chodzi o to, że chcę, aby wykresy były w stałej odległości od siebie, we wszystkich punktach poza zagięciami. Bo przesuwając w pionie, jak mam funkcję bardziej rosnącą, to automatycznie i przesunięcie się zmniejsza (wizualnie)



Tutaj mam przykład działania tego co mam.
ODPOWIEDZ