Równanie prostej przechodzącej przez dwa punkty

0

Cześć! Mam mały problem. Dopiero zaczynam swoją przygodę z Javą i nie do końca wiem jak co działa. Mam za zadanie napisać równanie prostej przechodzącej przez punkty określone przez końce podanej linii. Stworzyłam klasę Point oraz Line

public class Point {
    int x;
    int y;
}

public class Line extends Point {
    Point head;   
    Point tail;     
} 

Czy ktoś byłby w stanie pomóc mi stworzyć taką funkcję, która przyjmuje obiekt Point oraz Line i liczy równanie prostej?
Z góry dziękuję za pomoc :)

2

Dlaczego punkty w klasie Line nazwałeś głowa i ogon?
Dlaczego linia dziedziczy po punkcie? (W rzeczywistości prosta to nieskończona ilość punktów, ale w tym wypadku dziedziczenie nic nam nie da).

Prosta określana jest wzorem y = ax + b
Potrzebujesz wyznaczyć a oraz b.

Czy ktoś byłby w stanie pomóc mi stworzyć taką funkcję, która **przyjmuje obiekt Point oraz Line** i liczy równanie prostej?
Ale dlaczego tak?

Napisz funkcję która przyjmuje dwa punkty i wyznacza 2 wspołrzędne.
Coś w stylu

public Line calculateFactors(Point firstPoint, Point secondPoint) {

tutaj skorzystaj z gotowego wzoru i zwróć te dwa współczynniki
return new Line(x1, x2)
}

Sama nazwa calculateFactors też do przemyślenia, ale zostawiam to Tobie.

Gdzie Line to będzie coś takiego

public class Line {
BigDecimal slopeFactor;
BigDecimal intercept;

dodaj tutaj konstruktor
oraz pobaw się toString() aby zrobić takie wyświetlanie jakie Ci się podoba
}

Wzór na te współczynniki masz tutaj: https://www.matemaks.pl/rownanie-prostej-przechodzacej-przez-dwa-punkty.html

1
Alexandr.r napisał(a):

Stworzyłam klasę Point oraz Line

Bardzo słabo że zacząłeś od czegoś takiego. To jest typowe niezdrowe projektowanie klas.

Zacznij od rozwiązania tego problemu na zwykłych zmiennych int lub float, i jak już będziesz miał działający program - wtedy spróbuj wyciągnąć jakieś klasy z niego.

0
Alexandr.r napisał(a):

Czy ktoś byłby w stanie pomóc mi stworzyć taką funkcję, która przyjmuje obiekt Point oraz Line i liczy równanie prostej?

Masz do tego wzory. Pytanie, co to ma dalej robić. Co to znaczy "liczy równanie prostej"? Chcesz to narysować?

0

y1=ax1+b
y2=ax2+b

---

y1-y2=a[x1-x2]

a=[y1-y2]/[x1-x2]

w 2D mozna sobie poradzic

---


[y1,y2]=a[x1,x2]

a=[y1,y2]/[x1,x2]

w matlabie to dziala

0

miałam w poleceniu zadania stworzyć strukturę przeznaczoną do reprezentacji punktu oraz linii oraz miałam podane jak one mają wyglądać

0
Alexandr.r napisał(a):

miałam w poleceniu zadania stworzyć strukturę przeznaczoną do reprezentacji punktu oraz linii oraz miałam podane jak one mają wyglądać

Od kogo to polecenie? Nazwy głowa i ogon nie są prawidłowe bo sugeruje to, że prosta ma początek i koniec. To byłby wtedy odcinek, a nie prosta.
Linia prosta powinna mieć współczynnik kierunkowy oraz wyraz wolny. Dlatego w swojej wypowiedzi wyżej podałem coś takiego

public class Line {
BigDecimal slopeFactor;
BigDecimal intercept;

}

Te współczynniki to pojedyncze wartości, a nie punkty.

0
Alexandr.r napisał(a):

miałam w poleceniu zadania stworzyć strukturę przeznaczoną do reprezentacji punktu oraz linii oraz miałam podane jak one mają wyglądać

To jest najgłupsza rzecz chyba jaką słyszałem w życiu.

Nie wiem kto Ci takie polecenia daje, ale uciekaj od niego jak najdalej.

0
Riddle napisał(a):
Alexandr.r napisał(a):

miałam w poleceniu zadania stworzyć strukturę przeznaczoną do reprezentacji punktu oraz linii oraz miałam podane jak one mają wyglądać

To jest najgłupsza rzecz chyba jaką słyszałem w życiu.

Nie wiem kto Ci takie polecenia daje, ale uciekaj od niego jak najdalej.

Nie przesadzajmy.
Po pierwsze jest możliwe, że OP coś delikatnie przekręca, nie pisze całośći więc zadanie może mieć sens.
Po drugie to akurat prosta jest wyznaczana przez 2 punkty :-) więc jest całkiem dobrze. Jedynie to head, tail średnio pasuje - więc coś tam pewnie jeszcze było w tym zadaniu.

0
jarekr000000 napisał(a):

Po drugie to akurat prosta jest wyznaczana przez 2 punkty :-) więc jest całkiem dobrze.

No właśnie nie dobrze, bo autorowi nic nie da ta klasa Line. Równie dobrze mógłby mieć dwie zmienne Point head i Point tail i na to samo by wyszło, tylko bez niepotrzebnych constraintów. Poza tym jeszcze Line dziedziczy z Point, to już w ogóle mega słaby pomysł.

0
public class Main {

    private static String createLineFunction(float xa, float ya, float xb, float yb) {

        float a = (ya - yb) / (xa - xb);
        float b = ya - (ya - yb) / (xa - xb) * xa;

        return String.format("y = %.2fx + %.2f", a , b);
    }

    public static void main(String[] args) {
        float xa = 3;
        float ya = -5;
        float xb = -1;
        float yb = 7;

        System.out.println(createLineFunction(xa, ya, xb, yb));
    }
}
1
Riddle napisał(a):

No właśnie nie dobrze, bo autorowi nic nie da ta klasa Line. Równie dobrze mógłby mieć dwie zmienne Point head i Point tail i na to samo by wyszło, tylko bez niepotrzebnych constraintów. Poza tym jeszcze Line dziedziczy z Point, to już w ogóle mega słaby pomysł.

Nie do końca rozumiem, co w tym złego - oprócz nazw i dziedziczenia. W geometrii euklidisowej prostą można jednoznacznie opisać za pomocą dwóch punktów znajdujących się na niej więc taka reprezentacja będzie zawsze dobra (z wyjątkiem sytuacji, gdy first i second będą wskazywały na ten sam punkt).


class Line {
  private Point first;
  private Point second;

  public double getOffset() {
     // zwraca b z y=ax+b
  }

  public double getSlope() {
     // zwraca a z y=ax+b
  }

  // i cokolwiek dusza zapragnie, np. kąt nachylenia prostej, forma normalna itp. 
}
0
wartek01 napisał(a):
Riddle napisał(a):

No właśnie nie dobrze, bo autorowi nic nie da ta klasa Line. Równie dobrze mógłby mieć dwie zmienne Point head i Point tail i na to samo by wyszło, tylko bez niepotrzebnych constraintów. Poza tym jeszcze Line dziedziczy z Point, to już w ogóle mega słaby pomysł.

Nie do końca rozumiem, co w tym złego - oprócz nazw i dziedziczenia. W geometrii euklidisowej prostą można jednoznacznie opisać za pomocą dwóch punktów znajdujących się na niej więc taka reprezentacja będzie zawsze dobra (z wyjątkiem sytuacji, gdy first i second będą wskazywały na ten sam punkt).

Najpierw Wcześniej się robi implementację, później dopiero refaktor i budowanie klas.

0

Mi wyszło tak po refaktorze, uważacie że dobrze?

class Point {
    private final float x;
    private final float y;

    Point(float x , float y) {
        this.x = x;
        this.y = y;
    }

    public float getX() {
        return x;
    }
    public float getY() {
        return y;
    }
}

class Line {
    Point start;
    Point end;

    Line (Point start, Point end) {
        this.start = start;
        this.end = end;
    }

    public String createLineFunction() {
        float a = (start.getY() - end.getY()) / (start.getX() - end.getX());
        float b = start.getY() - a * start.getX();
        return String.format("y = %.2fx + %.2f", a , b);
    }
}



public class Main {
    public static void main(String[] args) {
        Line line = new Line(
                new Point(3, -5),
                new Point(-1, 7)
        );
        //y = -3,00x + 4,00
        System.out.println(line.createLineFunction());
    }
}

Domyślam się że wyświetlana funkcja nie działa zbyt dobrze, np jak a = 1 to nie powinno pisać 1.00x tylko x a jak b jest 0 to też nie powinno pisać +0.00 itp ale nie chciałem zabardzo psuć autorowi tematu zabawy.

0

@Yarilo: jest lepiej, natomiast to, co sam bym poprawił to wydzieliłbym wyliczanie współczynników a i b do oddzielnej metody. Dzięki temu w jednej metodzie będziesz miał wyznaczanie współczynników, a w drugiej ich formatowanie. Np.

class Line {
    Point start;
    Point end;

    Line (Point start, Point end) {
        this.start = start;
        this.end = end;
    }

    float[] getLinearCoefficients() {
      float[] result = new float[2];
      result[0] = (start.getY() - end.getY()) / (start.getX() - end.getX());
      result[1] = start.getY() - a * start.getX();

      return result;
    }

    String getLinearEquationCoefficients() {
      float[] coefficients = getLinearCoefficients();

      return String.format("y = %.2fx + %.2f", coefficients[0] , coefficients[1]);
    }
}
1

Autor się w ogóle nie wysilil - nawet nie odpowiedział na nasze pytania. A wy mu gotowce trzaskacie. Nie ma tym polega nauka.

0
wartek01 napisał(a):

@Yarilo: jest lepiej, natomiast to, co sam bym poprawił to wydzieliłbym wyliczanie współczynników a i b do oddzielnej metody. Dzięki temu w jednej metodzie będziesz miał wyznaczanie współczynników, a w drugiej ich formatowanie. Np.

No żeby to na prawdę było obiektowo, to powinno wyglądać jakoś tak:

class Line {
  private Point start;
  private Point end;

  Line (Point start, Point end) {
    this.start = start;
    this.end = end;
  }

  float getSlope() {
    return start.getY() - end.getY()) / (start.getX() - end.getX();
  }

  float getIntercept() {
    return start.getY() - getSlope() * start.getX();
  }
}

// ...

public static void main(String[] args) {
  Line line = new Line(//... );

  return String.format("y = %.2fx + %.2f", line.getSlope(), line.getIntercept());
}
4

No dobra, a czy ktoś z was pomyślał o przypadku brzegowym, gdzie start.x == end.x?

Wtedy start.x - end.x będzie równe zero. A wy chcecie przez to dzielić. Tak nie można przecież ;)

1
Riddle napisał(a):

No żeby to na prawdę było obiektowo, to powinno wyglądać jakoś tak:

Niekoniecznie, wszystko zależy od tego, jak traktujemy Line. Zapis w postaci Stringa może być albo własnością obiektu, albo też operacją na obiekcie - zależy od potrzeb i kontraktu klasy, ale nie ma żadnej zasady w stylu "jeśli ma być obiektowo to musi być tak, że formatowanie obiektów musi być z zewnątrz.

0
wartek01 napisał(a):
Riddle napisał(a):

No żeby to na prawdę było obiektowo, to powinno wyglądać jakoś tak:

Niekoniecznie, wszystko zależy od tego, jak traktujemy Line. Zapis w postaci Stringa może być albo własnością obiektu, albo też operacją na obiekcie - zależy od potrzeb i kontraktu klasy, ale nie ma żadnej zasady w stylu "jeśli ma być obiektowo to musi być tak, że formatowanie obiektów musi być z zewnątrz.

Jeśli traktujesz Line tak jak opisałeś, to tak czy tak liczenie współczynników powinno być wyniesione do innej klasy, i mamy ten sam efekt.

0
LukeJL napisał(a):

No dobra, a czy ktoś z was pomyślał o przypadku brzegowym, gdzie start.x == end.x?

Wtedy start.x - end.x będzie równe zero. A wy chcecie przez to dzielić. Tak nie można przecież ;)

Nasz święty od kilkuset lat układ kartezjańśki ( o jednakowej naturze składowych x i y) ma swoje ograniczenia.

W niewielu dziedzinach, np w elektonice, ludzie są oswajani, że nie jest jedynym. Sygnał elektryczne można rozpatrywać w dziedzinie czasu (czas napiecie), częstotliwości / fazy / impulsowej itd... a dobrze wykształcony absolwent studiów elektroniki przemieszcza sie miedzy nimi płynnie.
Każdy z ukladów wspólrzednych ma punkty "specjalne", czy to delta Diraca, czy inne. Już same liczby urojone (podstawa w elektronice) świadczą, ze nasza matematyka od liczenia jabłek i pomarańcz trochę pęka.

Line podana przez @Riddle ma słabość, że patrzy tylko punktami, mz błędnie, najmniej efektywny sposób zamodelowania, co zmusza do dzielenia przez zero. Ujęcie analityczne y = a*x +b nie radzi sobie z pionową. Chyba względnie odporne jako układ równań (ale to bomba z opóznionym zapłnem: układ da sie napisac bezwarunkowo, ale rozwiazując go trafimy na to samo)

Ja tak sobie tylko pstrykam per-analogiam. Sądzę, że ktoś z dobrym wyksztalceniem geometrycznym (astronom? geodeta? nawigator?) był dał tu świeży model matematyczny, bo my to tylko Jasie.

0

Ax + By + C = 0 by @LukeJL to chyba to jest dobre zamodelowanie linii - w sensie jej tożsamości, istoty, jest proste, nie wymaga manipulacji warunkami, da sie zapisać jako trzy parametry w strukturach danych / plikach.

Ale wymaga przekształcenia w celu jej wymalowania -> d nadal z tyłu. To nie znaczy że nie da się zrobić, ale znów wpadamy w warunki (o czym zresztą piszesz)

0
AnyKtokolwiek napisał(a):

Ale wymaga przekształcenia w celu jej wymalowania -> d nadal z tyłu. To nie znaczy że nie da się zrobić, ale znów wpadamy w warunki (o czym zresztą piszesz)

To nie jest "d... nadal z tyłu" tylko bardzo spoko podejście. Wtedy np. getLinearFunction() może ci rzucić wyjątkiem w przypadku linii pionowej - czyli prosta istnieje, nie istnieje jedynie funkcja liniowa ją opisująca.

0
wartek01 napisał(a):
AnyKtokolwiek napisał(a):

Ale wymaga przekształcenia w celu jej wymalowania -> d nadal z tyłu. To nie znaczy że nie da się zrobić, ale znów wpadamy w warunki (o czym zresztą piszesz)

To nie jest "d... nadal z tyłu" tylko bardzo spoko podejście. Wtedy np. getLinearFunction() może ci rzucić wyjątkiem w przypadku linii pionowej - czyli prosta istnieje, nie istnieje jedynie funkcja liniowa ją opisująca.

Mówiąc o malowaniu linii, trzeba dać jakiegoś if a nie wyjątek, a zbyt dużo warstw może przeszkadzać, "zwracanie" wyjątku jak potrzebujesz konkret może być nieco biedackie

... ale wiesz co, jak wpadłem w ten wątek nie miałem wyobrażenia, ale to dojrzało. Czy innym jest model, w szczególności bezifowy zapis gdzieś do pliku (równanie sprowadzające do zera wg Luke jest szczególnie eleganckie), czym innym kwestie implementacyjne (rysowanie, ocena przecinania się itd), i tu, jakolwiek byśmy ustawili "teorię", to "praktyka" wymusza istnienie if-y, być moze dla odmiennych kontekstów (układ nie kartezjański a radialny - ale też if'y bedą)

0
AnyKtokolwiek napisał(a):

Mówiąc o malowaniu linii, trzeba dać jakiegoś if a nie wyjątek, a zbyt dużo warstw może przeszkadzać, "zwracanie" wyjątku jak potrzebujesz konkret może być nieco biedackie

Nie mówię o malowaniu linii. Mówię o tym, że klasa Line może mieć metody zwracające je w pewnej postaci. Funkcja liniowa nie może zaistnieć w przypadku gdy jest to linia równoległa do osi Y (bo nie będzie to funkcja), więc metoda getLinearFunction musi taki scenariusz obsłużyć - i wspomniany if być tam musi. Faktem jest, że to nie musi być wyjątek, ale np. jakiś pusty Optional czy co tam sobie zażyczysz.

0
wartek01 napisał(a):

Nie mówię o malowaniu linii. Mówię o tym, że klasa Line może mieć metody zwracające je w pewnej postaci. Funkcja liniowa nie może zaistnieć w przypadku gdy jest to linia równoległa do osi Y (bo nie będzie to funkcja), więc metoda getLinearFunction musi taki scenariusz obsłużyć - i wspomniany if być tam musi. Faktem jest, że to nie musi być wyjątek, ale np. jakiś pusty Optional czy co tam sobie zażyczysz.

Moze mieć metody oczywiście.

Róznimy się w punkcie, że rozważasz JAK zrobić getLinearFunction a ja CZY.
Bo skoro nie jest 100% drogą NA PRZYKŁAD do malowania (i do innych czynności - i tak malowanie np pionowej trzeba zrealizować inaczej, wyjątek czy Optional bez znaczenia, nie pomoże w tym), pytanie czy jest potrzebna do czegoś, czy tylko z rozpędu, przez przyzwyczajenie do szkolnego układu kartezjańskiego.

Dawno już gadamy poza bezpośrednim pytaniem wątku ...

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