Prosta sprawa? zsynchronizowany ruch po okręgu

0

Witam. Kula niebieska rusza się po okręgu, tak jak przedstawiłem to na obrazku (sam rysowałem :P). Mój problem polega na tym, żeby czerwona kula poruszała się bezpośrednio obok niebieskiej kuli, ale w nieco oddalonej odległości. Inaczej mówiąc, gdy kula niebieska dotrze do dolnej krawędzi okręgu po którym się porusza, czerwona też powinna się w tym samym momencie znaleźć na dolnej krawędzi swojego okręgu.

user image

Niebieska kula się porusza ładnie tym kodem:

kat += (Math.PI / 124) * 2;
x += Math.cos(kat) * speed;
y += Math.sin(kat) * speed;

gdzie kąt jak sama nazwa mówi to kąt
x to położenie x kuli
y to położenie y kuli
speed to ewentualne przyspieszenie

kombinuje od 2 dni, żeby ta przeklęta czerwona kula przylegała do niebieskiej, i nie mogę wykombinować jak to zrobić, żeby była do niej przyłączona :c

Rozwiązaniem tego problemu prawie na bank będą tylko 2 linijki...

x2 = ?
y2 = ?

gdzie x2 to położenie x czerwonej kuli a y2 to położenie y czerwonej kuli, eh :P

Ma ktoś pomysł jak rozwiązać tę zagadkę?

1

Ruch po okręgu.

Generalnie chcesz, żeby prędkość kątowa obu kul pozostawała taka sama. Innymi słowy pierwsza kula pokonuje drogę 2PIr1 w czasie t, a druga pokonuje 2PIr2 też w czasie t.

Czyli (po przekształceniu wzorów na prędkość): speed1 = r1*speed2/r2 :P

EDIT: tak speed1 to prędkość pierwszej kulki, a r1 to promień okręgu po którym się porusza.

0

https://pl.wikipedia.org/wiki/Pr%C4%99dko%C5%9B%C4%87_k%C4%85towa

Twoje kule poruszaja sie z jednakowa predkoscia liniowa wiec nie poruszaja sie synchronicznie. Musisz powiazac predkosc liniowa z odlegloscia od srodka

0
Biały Szczur napisał(a):

Musisz powiazac predkosc liniowa z odlegloscia od srodka

Problem w tym, że środek jest nieznaną wartością, której jeśli nie trzeba, to wolałbym nie szukać bo zmienia się ona z każdą zmianą kierunku kuli.
Znam współrzędne kuli niebieskiej, a co więcej, ona porusza się eliptycznie w różnych kierunkach, a czerwona powinna lecieć w tym samym kierunku w którym obecnie leci niebieska

user image

xfin napisał(a):

Czyli (po przekształceniu wzorów na prędkość): speed1 = r1*speed2/r2 :P
Eh, brzmi mądrze, ale da się to jakoś przełożyć do praktycznego zastosowania? czym są podane przez Ciebie wartości? speed1 to prędkość kuli niebieskiej? r1 to promień? :c

0

W pierwszym poście opisałeś zupełnie inny (dużo prostszy) problem:

Kula niebieska rusza się po okręgu
. Odpowiedź, którą dał @xfin dotyczy tego prostego problemu.

0

Odnośnie drugiego obrazka to w każdym jednym momencie wyznaczałbym kierunek prostopadły do funkcji po której poruszają się kulki (prostopadły do stycznej), i odsuwał jedną kulkę na jedną stronę, a drugą na drugą.

0

Serio, nie da się tej czerwonej kuli sztywno przylepić do niebieskiej bez takiego kombinowania? Czerwona kula powinna być sztywno przylepiona do niebieskiej, po jej lewej stronie, oddalona od niej aby o kawałek.
Na bank możliwe jest napisanie tego w 2 linijkach, w końcu znany jest i kierunek kuli i jej położenie... trzeba tylko przylepić do niej drugą kule, eh :P Może wcześniej nie wyjaśniłem tego wystarczająco precyzyjnie, może teraz macie jakiś pomysł? :c

x2 = ?
y2 = ?
0

Dlaczego nie podejdziesz do tego domenowo? Tworzysz kulki, i potem dodajesz metody, dzięki którym obracasz ją wokół wspólnych punktów.

Na początek powtórka z matmy:
Ze wzorów:
x = r * sin(alfa);
y = r * cos(alfa);

gdzie:
x,y - współrzędne w kartezjańskich
r - promień okręgu
alfa - kąt

czyli:
x1 = r1 * sin(alfa);
y1 = r1 * cos(alfa);

x2 = r2 * sin(alfa);
y2 = r2 * cos(alfa);

przechodząc na przyrosty
dx1 = r1 * d(sin(d(alfa)));
dy1 = r1 * d(cos(d(alfa)));
...

gdzie:
d(sin) - zmiana sinus
d(alfa) - zmiana kąta alfa

dodatkowo trzeba uwzględnić translację
dx1 + v = r1 * d(sin(d(alfa))) + v;
dy1 + v = r1 * d(cos(d(alfa))) + v;
v - wektor przesunięcia środka

przechodząc na przyrosty wektora
dx1 + dvx = r1 * d(sin(d(alfa))) + dvx
analogicznie dla dy1

Teraz przechodzimy na Javę:

public class CirclingSphere {
    private double currentX;
    private double currentY;
    private int currentDegreeNumber;
    private double radius;

    public CirclingSphere(double radius){
        this.radius = radius;
        this.currentX = 0;
        this.currentY = radius;
        this.currentDegreeNumber = 0;
    }

    public void rotate(int angleInDegrees){
        double newRadians = toRadian(currentDegreeNumber + angleInDegrees);
        double currentRadians = toRadian(currentDegreeNumber);

        this.currentX = this.currentX + (radius * getSinusDifference(currentRadians, newRadians));
        this.currentY = this.currentY + (radius * getCosinusDifferential(currentRadians, newRadians));

        this.currentDegreeNumber = this.currentDegreeNumber + angleInDegrees;
    }

    public void translate(double x, double y){
        this.currentX = this.currentX + x;
        this.currentY = this.currentY + y;
    }

    public double getX(){
        return this.currentX;
    }

    public double getY(){
        return this.currentY;
    }

    private double getSinusDifference(double currentRadians, double newRadians){
        return Math.sin(newRadians) - Math.sin(currentRadians);
    }

    private double getCosinusDifferential(double currentRadians, double newRadians){
        return Math.cos(newRadians) - Math.cos(currentRadians);
    }

    private double toRadian(int numberOfDegrees){
        return (Math.PI * numberOfDegrees)/180.0;
    }
}

Czas na testy:

public class Main {
    public static void main(String[] args){
        CirclingSphere first = new CirclingSphere(1);
        CirclingSphere second = new CirclingSphere(1.25);

        Consumer<Consumer<CirclingSphere>> bothConsumer = circlingSphereConsumer -> {
            circlingSphereConsumer.accept(first);
            circlingSphereConsumer.accept(second);

            System.out.println("First:" + asString(first));
            System.out.println("Second:" + asString(second));
        };

        bothConsumer.accept((cs -> cs.translate(0.1, -0.2))); // przesuwamy do punktu 0.1;-0.2
        for(int i=0; i<12; i++){
            bothConsumer.accept(cs -> cs.rotate(30)); // obracamy o 30 stopni w kazdym kroku
        }
    }

    private static String asString(CirclingSphere circlingSphere){
        return rounded(circlingSphere.getX())+ ";" + rounded(circlingSphere.getY());
    }

    private static double rounded(double d){
        return Math.round(d * 100)/100.0;
    }
}
0

Poprosić człowieka, żeby drzwi otworzył, to ten ci całe wrota buduje xD Obawiam się, że nie przeczytałeś ostatniego mojego posta zanim wysłałeś swojego i niestety chyba nie do końca mnie zrozumiałeś... Także wciąż proszę o pomoc :c

0

Nie da się na sztywno przylepić czerwonej kulki do niebieskiej, bo one się poruszają z różnymi prędkościami. Jeżeli niebieska (jak sugeruje rysunek) porusza się po łukach okręgów, to musisz znać położenie środków tych okręgów.

0
bogdans napisał(a):

Nie da się na sztywno przylepić czerwonej kulki do niebieskiej, bo one się poruszają z różnymi prędkościami. Jeżeli niebieska (jak sugeruje rysunek) porusza się po łukach okręgów, to musisz znać położenie środków tych okręgów.

Eh, jesteś pewien? Jeśli tak to już chyba nic nie wykombinuje :c

A gdyby niebieska kulka się nie poruszała, tylko stała w miejscu ale obrócona w jakimś kierunku, na przykład w lewo, albo poruszała się po prostej?
user image

0

Jak po prostej, to nie ma problemu:

x2 = x + pewnaStała;
y2 = y + innaStała;

A zdania

A gdyby niebieska kulka się nie poruszała, tylko stała w miejscu ale obrócona w jakimś kierunku, na przykład w lewo
nie rozumiem. Kulka obrócona niczym się nie różni od kulki nieobróconej.

0
bogdans napisał(a):

Jak po prostej, to nie ma problemu:

x2 = x + pewnaStała;
y2 = y + innaStała;

no tak, tylko, że ona nie zawsze rusza się tylko po prostej, i gdy tylko zmieni kierunek, ten kod już się nie przyda :c

A zdania

A gdyby niebieska kulka się nie poruszała, tylko stała w miejscu ale obrócona w jakimś kierunku, na przykład w lewo
nie rozumiem. Kulka obrócona niczym się nie różni od kulki nieobróconej.

oj, kulka czy samochód... komputer tego nie rozróżni :D i tak samo jak samochód jest zawsze w którąś stronę zwrócony, tak samo i moja kulka jest w którąś stronę zwrócona :P

0

user image
taka analogia:
wiesz w którym miejscu stoi bohater, i wiesz w którą stronę jest obrócony i potrzebujesz zespawnować dla niego broń, po jego prawej stronie.
nie możesz zrobić tego w ten sposób:

przedmiot.x = bohater.x -3;
przedmiot.y = bohater.y -3;

bo jak on się odwróci to wtedy te współrzędne nie będą już po jego prawej stronie. A więc pytanie, jaki będzie kod, żeby przedmiot zawsze spawnował się po jego prawej stronie?

1

Jeżeli fi jest kątem o jaki obrócił się bohater, to

przedmiot.x = bohater.x - 3*Math.cos(fi);
przedmiot.y = bohater.y - 3*Math.sin(fi);
0
bogdans napisał(a):

Nie da się na sztywno przylepić czerwonej kulki do niebieskiej, bo one się poruszają z różnymi prędkościami. Jeżeli niebieska (jak sugeruje rysunek) porusza się po łukach okręgów, to musisz znać położenie środków tych okręgów.

Po co komu prędkość liniowa? Kule poruszają się z jednakową prędkością kątową

0
bogdans napisał(a):

Jeżeli fi jest kątem o jaki obrócił się bohater, to

przedmiot.x = bohater.x - 3*Math.cos(fi);
przedmiot.y = bohater.y - 3*Math.sin(fi);

Wprawdzie nie to nie jest rozwiązanie, ale to dzięki temu kodowi wreszcie mi się udało to rozwiązać :D dlatego wielkie dzięki :P
A poprawnym rozwiązaniem jest:

kulaCzerwona.x = kulaNiebieska.x+(odlegloscMiedzyKulami *Math.cos(kat+1.570796));
kulaCzerwona.y = kulaNiebieska.y+(odlegloscMiedzyKulami *Math.sin(kat+1.570796));

1.570796 bo tyle wynosi 90 stopni w radianach;

bogdans napisał(a):

Nie da się na sztywno przylepić czerwonej kulki do niebieskiej, bo one się poruszają z różnymi prędkościami. Jeżeli niebieska (jak sugeruje rysunek) porusza się po łukach okręgów, to musisz znać położenie środków tych okręgów.

i co, nie da się? :D

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