logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Program rysujacy wektory - Delphi (jak go napisać ?)

lukaszzk 15 Wrz 2007 16:14 6434 11
  • #1 4286166
    lukaszzk
    Poziom 14  
    Posty: 137
    Pomógł: 4
    Ocena: 7
    Witam Wszystkich

    Na samym początku chciałbym podziękować osobom które pomogą w rozwiązaniu mojego problemu.

    Wrzesień już za pasem, nauka się zaczęła a wraz z nią nowe wyzwania i niestety nowe problemy, to tyle tytułem wstępu :-D

    Pozwolę sobie teraz przejść do opisania mojego problemu:
    Programuje hobbystycznie w Delphi jednak ostatnio postawiono mi nowe wyzwanie.
    Jeśli już coś robiłem w Delphi to nie było to na pewno związane z grafiką a mój problem właśnie zahacza o ten piękny dział programowania.

    Otóż potrzebuje napisać program rysujący wektory, na początku chciałbym zaznaczyć ze nie musi to być oczywiście jakiś program CAD'owski (to był żart rzecz jasna :-))
    Chciałbym aby wektory dało się rysować myszką, tak jak np autokształty w programie MS Word czy Open Office.
    Oczywiście wektor powinien być zakończony strzałką, a poza tym wektor powinno dać się:
    - przesuwać
    - wydłużać
    - skracać
    - obracać
    - zmieniać kąt nachylenia
    To by było wszystko jeśli chodzi o opis aplikacji. Po prostu z wektorem powinno się dać robić to wszystko co z normalnym wektorem na papierze. Bardzo ważne jest to aby większość operacji wykonywać za pomocą myszki i ewentualnie menu kontekstowego. Z resztą to znaczy z obliczaniem współrzędnych względnych i bezwzględnych, kątów i długości sądzę że sobie sam powinienem poradzić.

    Poniżej zamieszczam kilka ideowych obrazków przedstawiających pracę w programie. Mam nadzieje że za bardzo nie skomplikowałem sprawy właściwie wszystko zawarte jest w temacie.

    Wektor aktywny:
    Program rysujacy wektory - Delphi (jak go napisać ?)
    Przesuwanie końca wektora:
    Program rysujacy wektory - Delphi (jak go napisać ?)
    Przesuwanie całego wektora:
    Program rysujacy wektory - Delphi (jak go napisać ?)
    Wektor nieaktywny:
    Program rysujacy wektory - Delphi (jak go napisać ?)
  • Pomocny post
    #2 4286431
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Zapomniałeś tylko napisać w czym dokładnie tkwi problem...
  • #3 4286766
    lukaszzk
    Poziom 14  
    Posty: 137
    Pomógł: 4
    Ocena: 7
    Może to będzie straszne ale pisze: w napisaniu aplikacji :-D

    Próbowałem coś sam działać ale chyba w ogóle źle zacząłem opierając wszytko o formularz CANVAS, całość była podobna do rysowania w paincie a więc edycja "statyczna" a mi chodzi o "dynamiczną" możliwość tworzenia grafiki a więc przesuwanie obiektu itp. A poza tym nie mogłem w ogóle sobie poradzić z tzw 'uchwytem" to takie małe kółeczka pojawiające sie np przy przesuwaniu autokształtu oraz z samym przesuwaniem obiektu.
    Kolejna problem polegał na tym że potrafiłem narysować kreskę a nie wektor.

    Niby taka prosta rzecz, to przecież tylko zwykły wektor a jednak sprawia trudności.:|
  • Pomocny post
    #4 4286956
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Po łebkach opisany algorytm...

    1.Rysowanie wektora robisz tak
    a)rysujesz kreskę
    b)rysujesz trójkąt na końcu (pozycję obliczasz z wykorzystaniem zamiany wartości x/y
    c)wypełniasz trójkąt czarnym kolorem
    d)jeżeli jest włączona opcja przesuwania wektora to dodatkowo rysujesz 3 kólka (na początku, na środku do przesuwania całego wektora i na końcu)

    2.Dane wektorów zapisujesz jako strukturę o np. takich parametrach:

    long x1,y1,x2,y2;
    x1,y1 to punkt początkowy a x2,y2 to punkt końcowy

    ew dalej jakieś dane koloru itp.

    Z tej struktury robisz tablicę. Tutaj masz dwie możliwości:
    a)Zwykła tablica jednowymiarowa - w tym momencie na starcie musisz zadeklarować ile maksymalnie wektorów będzie można było narysować (ew. można to obejść - za każdym razem gdy tablica zbliży się do wypełnienia inicjalizujesz nową, większą tablicę i kopiujesz tam dane)

    b)tzw. linked list(wybacz, wypadła mi polska nazwa) - każda struktura dodatkowo zawiera wskaźnik do poprzedniego/kolejnego elementu i przy pomocy tych wskaźników możesz chodzić po "tablicy". Wskaźniki są alokowane dynamicznie, dlatego jedynym ograniczeniem ilości wektorów jest wolna pamięć

    3.W programie robisz np. toolbara z opcjami:
    a)dodaj wektor
    b)przesuń wektor
    c)wykasuj wektor

    4.Działanie programu jest zależne od wybranej opcji:

    dla a-dodaj wektor
    Czekasz aż ktoś kliknie myszą, zapisujesz ten punkt do pamięci, czekasz aż puści klawisz myszy - zapisujesz ten punkt do pamięci
    Teraz do tablicy zapisujesz nowy punkt na jej koniec
    (w zależności od typu zapisu danych - dla zwykłej tablicy po prostu w pierwsze wolne pole zapisujesz dane do struktury i zwiększasz zmienną określającą liczbę zapisanych wektorów)

    dla b-przesuń wektor
    Czekasz na kliknięcie myszy następnie przeglądasz listę wektorów (od końca) i porównujesz pozycję myszki z początkiem/środkiem/końcem wektora. Jeżeli trafisz na zaznaczony wektor to obrysuj go innym kolorem i zacznij przesuwać razem z ruchem myszki

    dla c - to samo co w b, ale po natrafieniu na zaznaczony wektor po prostu go skasuj (jeżeli masz zwykłą tablicę a nie linked list to będziesz musiał skopiować wszystkie wektory w tablicy za kasowanym wektorem o jedno do przodu, żebyś w tablicy nie miał dziury)

    Co do samego rysowania wektorów to przy wywołaniu komendy rysowania przemierz tablicę wektorów od początku do końca i je rysuj wg. pkt.1
    Włącz też "double buffering" w okienku bo inaczej wszystko będzie strasznie migało.

    Rozszerzeniem aplikacji byłoby dodanie scrollbarów, żebyś mógł oglądać obszar większy niż okno aplikacji i dodanie opcji zoom in/zoom out. W praktyce jest to dużo matematyki (przeliczanie punktu ekranu na punkt w wirtualnym ekranie gdzie są twoje wektory)

    Jak masz jakieś bardziej konkretne pytanie to postaram się pomóc.
    Najlepiej najpierw przejrzyj tematy:
    -tablica
    -linked list (trudniej ale bardziej przyszłościowe niż zrobienie tego na tablicy)
    -rysowanie GDI
    -obsługa myszki
  • #5 4287038
    lukaszzk
    Poziom 14  
    Posty: 137
    Pomógł: 4
    Ocena: 7
    Bardzo dziękuję za słowa słowa porady, to dla mnie wiele znaczy.
    No to teraz czas na naukę obiecuje odrobić pracę domową i się dokształcić :-) z tablicami miałem już odczynienia, ale takimi rzeczami jak obsługa myszki czy linked list poprostu się nie zajmowałem bo nie były mi potrzebne (może nauczę sie czegoś nowego).
    Z góry chciałbym przeprosić za to że czasami mogę milczeć nawet przez tydzień ale cóż zrobić czasami są wyże priorytety a studia potrafią dać w kość dlatego liczę na cierpliwość.
    Co do pytań to na pewno jeszcze będzie ich trochę, ale najpierw dokształcę się i postaram coś napisać abyśmy mogli podyskutować na równym poziomie.
    Chciałbym jeszcze dodać że docelowo program ma obsługiwać ploter, mam już koncepcje na napisanie programu ale postanowiłem że program musi posiadać graficzny interfejs, na którym widać wszystko jak na dłoni, no bo wiadomo same cyferki zbyt wiele nie mówią a jak ktoś zobaczy kwadrat to już milej się robi. Więc zaczynam od wizualizacji całego procesu a z resztą powinienem sobie poradzić.

    Jeszcze raz dziękuje za zainteresowanie moim tematem
  • #6 4290898
    lukaszzk
    Poziom 14  
    Posty: 137
    Pomógł: 4
    Ocena: 7
    Poniżej zamieszczam pierwszą, jeszcze bardzo nieudolna wersje programu.
    Nie myślałem że całość będzie aż tak skomplikowana, pomimo kilku godzin pracy zbyt wiele nie osiągnąłem.

    Na ta chwile podstawowe problemy to:
    - kłopot z orientacją na płaszczycie, ponieważ funkcja którą zastosowałem do odczytu pozycji kursora odczytuje współrzędne na ekranie a nie współrzędne tylko na samym formularzu wystarczy przeciągnąć okienko programu i już mamy problem.
    Ideałem było by stworzenie w formularzu układu współrzędnych, którego środek znajdował by się w środku formularza i wykonywanie wszystkich operacji względem tego układu.
    - dobrze by było aby przy rysowaniu wektora włączyć animację rysowania żeby było widać jak prowadzimy wektor myszką (niewiem w ogóle czy można coś takiego zrealizować w Delphi)
    - i takie teoretyczne pytanie jak włączyć double buffering w Delphi
    Załączniki:
    • Wektory3.rar (166.16 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #7 4300740
    xtedek
    Poziom 17  
    Posty: 201
    Pomógł: 13
    Ocena: 14
    trochę ci to poprawiłem, ale muszę cię skarcić ponieważ nazywanie procedur np ghghjgh to nie jest dobre rozwiązenie.
    Zajęło mi to 5min a dodałem ci metodę na rysowanie - przeciągnij wciśniętym lewym przyciskiem na formie, w ogóle to trochę dużo sobie utrudniasz :)

    Co do animacji to musisz tutaj zastosować odświeżanie (czyszczenie i powtórne rysowanie wektorów przy MouseMove)
    Ogólnie bedziesz musiał zapisywać dane każdego wektora w tablicy, tak jak to napisał mój poprzednik
    Załączniki:
    • wektory.rar (169.86 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #8 4303082
    lukaszzk
    Poziom 14  
    Posty: 137
    Pomógł: 4
    Ocena: 7
    Dziękuje za pomoc !
    To zawsze jakiś maleńki kroczek do przodu, ale zawsze do przodu.
    Zgadzam sie z tobą że nazwa "ghghjgh" jest całkiem nie na miejscu, ale poprostu mnie zaskoczyłeś tą informacją, niewiem jak to sie stało ale normalnie to takich rzeczy nie robię - ale przyznaje się do błędu.

    Mam jeszcze taka prośbę czy kolega mógłby, zaprezentować jak zrobić animacje przy rysowaniu byłbym wdzięczny za przykładzik obrazujący działanie tej funkcji - oczywiście to jest tylko proźba.
  • Pomocny post
    #9 4303308
    maciek_slon
    Poziom 29  
    Posty: 942
    Pomógł: 143
    Ocena: 27
    A ja podrzucę coś takiego, narazie bez komentarza :-) Pooglądaj, spróbuj rozkminić o co chodzi a potem zadawaj pytania :-)
    Załączniki:
    • rysownik.rar (156.3 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #10 4314304
    Stepel
    Poziom 20  
    Posty: 490
    Pomógł: 26
    Ocena: 28
    maciek_slon , spoko rozwiązanie jak na takie rymowanki :) . Oczywiście dodane Form1.DoubleBuffered:=True; eliminuje miganie Kanwy.
  • #12 4327631
    lukaszzk
    Poziom 14  
    Posty: 137
    Pomógł: 4
    Ocena: 7
    Dziękuję za informację Piotrek_P, widzę że to dość ciekawy komponent i na pewno mu się przyjrzę z bliska. W przykładowym programie demo, tworzenie grafiki wygląda dość zaawansowanie.

Podsumowanie tematu

✨ Dyskusja dotyczy stworzenia w Delphi programu do rysowania wektorów z funkcjami interaktywnymi takimi jak przesuwanie, wydłużanie, skracanie, obracanie i zmiana kąta nachylenia wektorów. Autor ma doświadczenie hobbystyczne w Delphi, ale napotyka trudności z dynamiczną edycją grafiki, obsługą myszy oraz implementacją uchwytów (małych kółek do manipulacji obiektami). Zaproponowano podejście oparte na strukturach przechowujących współrzędne punktów początkowych i końcowych wektorów oraz tablicach lub listach powiązanych do zarządzania kolekcją wektorów. Wskazano na konieczność implementacji mechanizmu odświeżania (double buffering) w celu animacji rysowania i eliminacji migotania. Podano przykładowy algorytm rysowania wektora z trójkątną strzałką na końcu oraz uchwytami do przesuwania. Wskazano na problemy z koordynatami kursora względem formularza i potrzebę stworzenia układu współrzędnych z centrum w środku formularza. Zaproponowano komponent SimpleGraph jako potencjalne narzędzie do realizacji projektu. Dyskusja zawiera także przykładowy kod i sugestie dotyczące nazewnictwa procedur oraz technik animacji w Delphi.
Wygenerowane przez model językowy.
REKLAMA