Rysowanie Krzywej Beziera na podstawie czterech podanych punktów

Rysowanie Krzywej Beziera na podstawie czterech podanych punktów
R1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 7 lat
  • Postów:20
0

Witam. Mam do napisania program który rysuję z 4 podanych punktów krzywą Beziera. Program ogólnie działa bez zarzutu lecz potrzebuję jeszcze jednej funkcjonalności a mianowicie muszę po naciśnięciu np. lewego guzika myszy skończyć rysować obecną krzywą i rozpocząć rysowanie nowej lecz z możliwością dalszej edycji starych krzywych.Obecnie po narysowaniu jednej krzywej mogę ją dowolnie zmieniać, ale nie wiem już jak zrobić dodawanie dodatkowych krzywych i ich edycji.Niżej zamieszczam kod:

Kopiuj
import java.awt.*;
import java.awt.event.*;

public class Bezier extends Frame {
   Point[] punkty;
   int numpoints;
   double t;
   double k=.025;   
   int moveflag = 5;      
    MenuBar pasek;
    Menu plik;
   MenuItem newB, zamknij;
   
public   Bezier() {
      super("Krzywa Beziera");
      pasek=new MenuBar();
      plik=new Menu("Plik");
      newB=new MenuItem("Nowy");
      zamknij=new MenuItem("Zamknij");
      plik.add(newB);
      plik.add(zamknij);
      pasek.add(plik);
      setMenuBar(pasek);
   }
      
   public void init() {
   resize(600,600);
   setLayout(new FlowLayout());
   punkty = new Point[4];
   numpoints = 0;
   }

   public void paint(Graphics g) {
   setBackground(Color.lightGray);
   g.clearRect(0,0,size().width,size().height);
   for(int i=0;i<numpoints;i++) {
   g.setColor(Color.red);
   g.fillOval(punkty[i].x-2, punkty[i].y-2,4,4);
   g.setColor(Color.red);
         }
       Licz(g);
   }
   
   public void Licz(Graphics g) {
   if(numpoints == 4) {
   double x1,x2,y1,y2;
   x1 = punkty[0].x;
   y1 = punkty[0].y;
   for(t=k;t<=1+k;t+=k){
x2=(punkty[0].x+t*(-punkty[0].x*3+t*(3*punkty[0].x-punkty[0].x*t)))+t*(3*punkty[1].x+t*(-6*punkty[1].x+
punkty[1].x*3*t))+t*t*(punkty[2].x*3-punkty[2].x*3*t)+punkty[3].x*t*t*t;
y2=(punkty[0].y+t*(-punkty[0].y*3+t*(3*punkty[0].y-punkty[0].y*t)))+t*(3*punkty[1].y+t*(-6*punkty[1].y+
punkty[1].y*3*t))+t*t*(punkty[2].y*3-punkty[2].y*3*t)+punkty[3].y*t*t*t;
   g.setColor(Color.gray);
   g.drawLine((int)x1,(int)y1,(int)x2,(int)y2);
   x1 = x2;
   y1 = y2;
   }
   }

}

public boolean action(Event e, Object o) {
   if (e.target == newB) {
   numpoints = 0;
   repaint();
   return true;
   }
   else if(e.target == zamknij) {
      System.exit(0);
   }
   return false;

}
public boolean mouseDown(Event evt, int x, int y) {
   Point point = new Point(x,y);

   if(numpoints < 4) {
   punkty[numpoints] = point;
   numpoints++;
   repaint();
   }
   else
   for(int i=0;i<numpoints;i++)
   for(int j=-2;j<3;j++)
   for(int l=-2;l<3;l++)
   if(point.equals(new Point(punkty[i].x+j,punkty[i].y+l)))
   moveflag = i;
   return true;
   }
   public boolean mouseDrag(Event evt, int x, int y) {
   if(moveflag < numpoints) {
   punkty[moveflag].move(x,y);
   repaint();
   }
   return true;
   }
   public boolean mouseUp(Event evt, int x, int y) {
   moveflag = 5;
   return true;
   }   
public static void main(String args[]) {
   Bezier B=new Bezier(); B.init(); B.show();
   }
}
flowCRANE
Tytuł wątku powinien w sposób sensowny i w miarę wyczerpujący opisywać Twój problem; Pamiętaj, że wątki z nic nie mówiącymi tytułami z reguły lądują w koszu;
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
1

Musisz stworzyć kolekcję krzywych Beziera, a w metodzie paint() rysować je w pętli. Napisałem program do rysowania krzywych Beziera (w Swingu). Z boku panelu wyświetlam (korzystając z JTable) listę krzywych, zaznaczona krzywa rysowana jest grubiej. Użytkownik może edytować lub usunąć zaznaczoną krzywą.

Btw, w AWT jest funkcja rysująca krzywe Beziera (podajesz tylko punkty kontrolne), dlaczego wymyślałaś koło na nowo?


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
R1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 7 lat
  • Postów:20
0

Zdaję sobie sprawę że w Javie jest funkcja rysująca Beziera ale nasz prowadzący uparł się że musimy sami zaimplementować wzór podany przez niego.Czyli muszę utworzyć JTable i po narysowaniu 4 pkt ma mi tablicę przenieść do JTable i rozpocząć rysowanie od nowa tak?? Ale czy w tym miejscu nie muszę zmieniać funkcji na edycję pkt. a żeby odwoływała się do JTable czy będzie pamiętać jaki punkty są z jakiej tablicy??

edytowany 1x, ostatnio: rat12
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Po jakiejkolwiek zmianie w JTable jedną funkcją kopiujesz do tablicy np Point[] arr=new Point[N]; zaś druga funkcja rysuje z Point[] arr oczywiście nic nie robi jeżeli tablica zbyt krótka.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
R1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 7 lat
  • Postów:20
0

Chyba nie załapałem :/

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

JTable jest pomocnicze, można ją zastąpić innym komponentem (JList, JComboBox), w którym możliwe jest zaznaczenie wiersza. Podstawą jest kolekcja krzywych Beziera, np.

Kopiuj
ArrayList<Point[]> krzywe = ArrayList<Point[]>();

Możesz też zajrzeć do tego wątku krzywe beziera


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
R1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 7 lat
  • Postów:20
0

Już rozumiem po osiągnięciu 4 pkt. przekazujesz je do Arraylist gdzie są trzymane ale jak dodać do tego schematu możliwość edycji narysowanych pkt. muszę odwołać się do Arraylist??

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

U mnie wygląda to tak:

Kopiuj
    int index = table.getSelectedRow();
    if(index == -1)
    {
        JOptionPane.showMessageDialog(this,
                  "Zaznacz jakąś krzywą w oknie po prawej","",JOptionPane.INFORMATION_MESSAGE);
        return;
    }
    points = curves.get(index).points; //odczytanie punktów kontrolnych wskazanej krzywej
    numpoints = 4; //
    status = EDITION; //pole status zawiera informację co użytkownik robi, wpływa na działanie mousePressed i mouseClicked
    edited = index; //pole edited jest wykorzystywane przez funkcję paint, wskazana krzywa jest rysowana grubszą kreską 

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
R1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 7 lat
  • Postów:20
0

No tak ale Ty tutaj korzystasz z JTable myślałem a żeby zmodyfikować kod i dodać rozróżnianie na kliknięcia że jak prawy to rysuję pkt jak lewy to dodaję pkt do Arraylist a jak środkowy to przesunięcie pkt i próbowałem użyć

Kopiuj
isMetaDown()

gdzie użycie prawego powinno zwrócić true i postawienie pkt ale nie chce mi działać ;/

edytowany 1x, ostatnio: rat12
R1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 7 lat
  • Postów:20
0

Udało mi się poprawić kod i osiągnąć połowiczny sukces a mianowicie zaznaczam 4 pkt mogę je poprawić lecz nie rysuję mi krzywej. Dodałem do menu opcję dodaj krzywą po jej uruchomieniu i kliknięciu w dowolnym miejscu pojawia mi się krzywa i mogę dodawać nowe pkt które znowu mogę edytować lecz nie mogę ruszyć tych starych. Da się to jakoś przeskoczyć??

Kopiuj
import java.awt.*; 
import java.awt.event.*; 
import java.util.*;
 
public class Bezier extends Frame 
{ 
    Point[] punkty = new Point[4];; 
    int numpoints = 0; 
    double t; 
    double k=.025;    
    int moveflag = 5;       
    MenuBar pasek; 
    Menu plik; 
    MenuItem newB, zamknij;
    ArrayList<Point[]> krzywe = new ArrayList<Point[]>();   
 
    public   Bezier() 
    { 
        super("Krzywa Beziera"); 
        pasek=new MenuBar(); 
        plik=new Menu("Plik"); 
        newB=new MenuItem("Nowa krzywa"); 
        zamknij=new MenuItem("Zamknij"); 
        
        plik.add(newB); 
        
        pasek.add(plik); 
        plik.add(zamknij);
        setMenuBar(pasek); 
    } 
 
    public void init() 
    { 
        resize(600,600); 
        setLayout(new FlowLayout()); 
    } 
 
    public void paint(Graphics g) 
    { 
        setBackground(Color.lightGray); 
        g.clearRect(0,0,size().width,size().height); 
        //System.out.println(krzywe.size());
        for(int k=0;k<krzywe.size();k++)
        {
            Point[] points = krzywe.get(k);
            for(int i=0;i<4;i++) 
            { 
                g.setColor(Color.red); 
                g.fillOval(points[i].x-2, points[i].y-2,4,4); 
                g.setColor(Color.red); 
            } 
            licz(g,points); 
        }
        for(int i=0;i<numpoints;i++) 
        { 
            g.setColor(Color.red); 
            g.fillOval(punkty[i].x-2, punkty[i].y-2,4,4); 
            g.setColor(Color.red); 
        }        
    } 
 
    public void licz(Graphics g,Point[] punkty) 
    { 
        double x1,x2,y1,y2; 
        x1 = punkty[0].x; 
        y1 = punkty[0].y; 
        for(t=k;t<=1+k;t+=k)
        { 
            x2=(punkty[0].x+t*(-punkty[0].x*3+t*(3*punkty[0].x-punkty[0].x*t)))+t*(3*punkty[1].x+t*(-6*punkty[1].x+ 
            punkty[1].x*3*t))+t*t*(punkty[2].x*3-punkty[2].x*3*t)+punkty[3].x*t*t*t; 
            y2=(punkty[0].y+t*(-punkty[0].y*3+t*(3*punkty[0].y-punkty[0].y*t)))+t*(3*punkty[1].y+t*(-6*punkty[1].y+ 
            punkty[1].y*3*t))+t*t*(punkty[2].y*3-punkty[2].y*3*t)+punkty[3].y*t*t*t; 
            g.setColor(Color.gray); 
            g.drawLine((int)x1,(int)y1,(int)x2,(int)y2); 
            x1 = x2; 
            y1 = y2; 
        }  
    } 
 
    public boolean action(Event e, Object o) 
    { 
        if (e.target == newB) 
        { 
            moveflag = 10;
        } 
        else if(e.target == zamknij) 
        { 
            System.exit(0); 
        }    
        return false;  
    } 
    public boolean mouseDown(Event e, int x, int y) 
    { 
        Point point = new Point(x,y); 
 
        if(numpoints < 4) 
        { 
            punkty[numpoints] = point; 
            numpoints++; 
            repaint(); 
        }
        else if(numpoints == 4)
        {
             
            for(int i=0;i<numpoints;i++) 
            for(int j=-2;j<3;j++) 
            for(int l=-2;l<3;l++) 
            if(point.equals(new Point(punkty[i].x+j,punkty[i].y+l))) 
            moveflag = i; 
        }
        if(moveflag == 10)
        {  
            krzywe.add(punkty);      
            punkty = new Point[4];
            numpoints = 0;
            repaint();
        }   
        return true; 
    } 
    public boolean mouseDrag(Event e, int x, int y) 
    { 
        if(moveflag < numpoints) 
        { 
            punkty[moveflag].move(x,y); 
            repaint(); 
        } 
        return true; 
    } 
    public boolean mouseUp(Event e, int x, int y) 
    { 
        moveflag = 5; 
        return true; 
    }   
    public static void main(String args[]) 
    { 
        Bezier B=new Bezier(); 
        B.init(); 
        B.show(); 
    } 
}
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
1

Po wybraniu z menu nowej krzywej

Kopiuj
    public boolean action(Event e, Object o) 
    { 
        if (e.target == newB) 
        { 
            moveflag = 10;
        } 

moveflag ustawiasz na 10.
W mouseDown masz to

Kopiuj
        if(moveflag == 10)
        {  
            krzywe.add(punkty);      
            punkty = new Point[4];
            numpoints = 0;
            repaint();
        }

Powyższy kod wykona się już po pierwszym kliknięciu (po dodaniu pierwszego punktu). Wykona się zatem odrysowanie, w metodzie paint masz to

Kopiuj
        for(int k=0;k<krzywe.size();k++)
        {
            Point[] points = krzywe.get(k);
            for(int i=0;i<4;i++) 
            { 
                g.setColor(Color.red); 
                g.fillOval(points[i].x-2, points[i].y-2,4,4); 
                g.setColor(Color.red); 
            } 
            licz(g,points); 
        }

Ale w tablicy points są aktualnie cztery nulle.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
R1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 7 lat
  • Postów:20
0

Ok już wiem gdzie robiłem błąd a istnieje możliwość odwołania się do poprzednich pkt. a żeby mieć możliwość edycji wszystkich krzywych na raz ??

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Jest taka możliwość. Użytkownik klika w jakiś punkt, a Ty przeszukujesz ArrayList<Point[]>. Kliknięty punkt powinien leżeć w odpowiednim kole o promieniu 2 (bo tak punkty kontrolne widzi użytkownik). Ma to wadę, jeżeli punkty kontrolne z dwóch różnych krzywych prawie się pokrywają, to możesz wybrać krzywą niezgodną z intencją użytkownika. (Dlatego ja wybrałem takie rozwiązanie, że użytkownik wpierw wskazuje krzywą.)


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)