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

[Delphi] Jak rysować na Canvas używając zmiennych Extended?

bikemc 03 Kwi 2008 17:04 4414 17
REKLAMA
  • #1 4989309
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    Witam,
    Muszę narysować wykres, jednak korzystam ze zmiennych Extended (bo muszę - wymaga tego np. Tangens) i jak używam Funkcji Canvas.LineTo albo MoveTo to mam błąd że Integer nie jest kompatybilny z Extended.
    Może można jakoś zmienić typ Canvas by uwzględniał także extended (zmiennoprzecinkowy)?

    Pozdrawiam

    Moderowany przez Marek_Skalski:

    Poprawiłem tytuł i pisownię. Dodałem syntax. Zamykam.

  • REKLAMA
  • #2 4989378
    KeinXor
    Poziom 24  
    Posty: 511
    Pomógł: 62
    Ocena: 63
    Tak na szybko:
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod
  • #3 4989443
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    Nie działa system w uses :(
  • #4 4990218
    KeinXor
    Poziom 24  
    Posty: 511
    Pomógł: 62
    Ocena: 63
    pisz trochę jaśniej... co dokładnie "nie działa"
    do listy uses dopisz moduł System, jaką wersje delphi używasz ?
  • #5 4990717
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    Mam taki kod:
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    wyskakuje mi błąd:

    Invalid floating point operation wskazując na tangensa- może źle zdeklarowałem ??
  • REKLAMA
  • #6 4990869
    lelekx
    Poziom 30  
    Posty: 1220
    Pomógł: 158
    Ocena: 90
    Sprawdź, jaką wartość wejściową otrzymuje tangens przed wystąpieniem błędu. Jeszcze w podstawówce uczyli, że tg=sin(x)/cos(x). Zastanów się, dla jakich x funkcja da wynik +/-∞ i jakie może to mieć to skutki dla programu.
  • #7 4990959
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    Wyskakuje 0:( a nie powinno:(
    Dodano po 1 [minuty]:

    Zaokrągla mi wynik, a ja potrzebuję do 4ch miejsc po przecinku:((
  • #8 4991010
    lelekx
    Poziom 30  
    Posty: 1220
    Pomógł: 158
    Ocena: 90
    I ma racje. Chyba nie pojmujesz, o co w tym chodzi... Wywołując kolejno:
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod

    1: Do zmiennej P trafia zaokrąglona do liczby całkowitej wartość zmiennej wartosckata
    2: Zamazujesz zmienną P i zapisujesz w niej zaokrągloną w górę wartość zmiennej wartosckata
    3: Ponownie zamazujesz zmienną P i zapisujesz w niej wartość zmiennej wartosckata zaokrągloną w górę.
    W takiej konstrukcji programu wykonanie etapów 1 i 2 mija się z celem, bo efekty tego nigdy nie zostaną wykorzystane.

    Jeżeli potrzebujesz wyświetlić wynik do 4 miejsc po przecinku, to skorzystaj zamiast z IntToStr z funkcji FloatToStrF:
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    Dodano po 2 [minuty]:

    A i jeszcze jedno. Chętnie będę pomagał dalej, jeżeli napiszesz co chcesz osiągnąć. Nie znając celu mogę Cię bezwiednie popychać w ślepą uliczkę sugerując nieoptymalne rozwiązania.
  • #9 4993329
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    W porządku. A jak chcę nanieść punkt na mój wykres za pomocą funkcji Canvas, to co muszę zrobić by miał miejsce po przecinku?
  • #10 4993983
    lelekx
    Poziom 30  
    Posty: 1220
    Pomógł: 158
    Ocena: 90
    Cytat:
    w porządku, a jak chcę nanieść na mój wykres za pomocą funkcji Canvas to co muszę zrobić? by miał miejsce po przecinku??

    Niech zgadnę, chodzi Ci o tekst?
    Jeżeli tak, to:
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod
  • #11 4994038
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    Nie, nie chodzi o tekst:) Punkty na płaszczyźnie z dużą dokładnością:) I są one po przecinku np 0,04 albo 0,4. Jak to zrobić?
  • REKLAMA
  • #12 4994114
    lelekx
    Poziom 30  
    Posty: 1220
    Pomógł: 158
    Ocena: 90
    Musisz zwiększyć rozdzielczość ekranu do np. 2048x1536 lub bezpośrednio generować wynik na drukarkę - tu osiągniesz dużo lepsza rozdzielczość. Niestety nie da się stawiać punktów na ekranie o niecałkowitych koordynatach.
  • REKLAMA
  • #13 4994750
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    lelekx
    A można skalę zmniejszyć? Na przykład, zamiast 0,4 mnożę to razy 10 i mam 4,0.
    Teraz skalę bym chciał (optycznie zmniejszyć razy 10). Jak myślisz?
  • #14 4994884
    lelekx
    Poziom 30  
    Posty: 1220
    Pomógł: 158
    Ocena: 90
    Tak, jest to realne. Musiałbyś stworzyć obiekt, który miałby swój Canvas i na nim rysować zamiast na ekranie. Taki obiekt o rozdzielczości np. 10x większej niż oczekiwany wynik. Następnie przeskalować bitmapę i wyświetlić na formie.

    Jeżeli chodzi o rysowanie po Canvas poza formą, to możesz skorzystać z obiektu TBitmap - stworzyć go dynamicznie i operować na podobiekcie Canvas.

    Co do skalowania, możesz skorzystać z metody StretchDraw, ale to nie jest najszczęśliwszy pomysł; alternatywne rozwiązanie jest tu: http://home.hccnet.nl/david.dirkse/math/bitmap/resize.html - ładnie skaluje bitmapy.
  • #15 4996847
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    A jak utworzyć taki obiekt? Mógłbyś dać przykład i na nim operować?
  • #16 4997692
    lelekx
    Poziom 30  
    Posty: 1220
    Pomógł: 158
    Ocena: 90
    Przykład trochę długaśny, ale działa (D6 Personal):
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    Własne komentarze umieściłem w klamrach.
  • #17 4998236
    Fyszo
    Poziom 37  
    Posty: 3987
    Pomógł: 223
    Ocena: 115
    lelekx napisał:
    Musiałbyś stworzyć obiekt, który miałby swój Canvas i na nim rysować zamiast na ekranie. Taki obiekt o rozdzielczości np. 10x większej niż oczekiwany wynik. Następnie przeskalować bitmapę i wyświetlić na formie.


    Ale po co ułamki najpierw mnożyć, a potem przy skalowaniu dzielić przez to samo? Przecież można rysować na obszarze docelowym (ew. na buforze tego samego rozmiaru), wszelkie obliczenia wykonywać normalnie, a tylko wynik (piksele, linie itp.) wklejać jako całkowity na treść obrazka.

    bikemc napisał:

    bo zaokrągla mi wynik, a ja potrzebuję do 4ch miejsc po przecinku:((


    Będziesz musiał zaokrąglać. Bo rozmiar wykresu np. f(x)=tan(x) wyjdzie 31400 punktów szerokości, od wysokości nie wspominając.
  • #18 5000912
    bikemc
    Poziom 13  
    Posty: 137
    Ocena: 2
    Mam max 5 stopni:) Więc cała funkcja tangens mnie nie interesuje;)

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy problemu rysowania wykresu na obiekcie Canvas w Delphi przy użyciu zmiennych typu Extended, które nie są bezpośrednio kompatybilne z funkcjami Canvas.LineTo i MoveTo oczekującymi wartości Integer. Zaproponowano konwersję wartości Extended na Integer za pomocą funkcji Round, Ceil i Floor z modułów System i Math, jednak autor zgłaszał problemy z ich użyciem i potrzebę zachowania precyzji do czterech miejsc po przecinku. Wyjaśniono, że funkcje te zaokrąglają do liczb całkowitych, co jest niezgodne z wymogiem precyzyjnego pozycjonowania punktów na wykresie. Omówiono, że Canvas nie obsługuje współrzędnych ułamkowych, więc konieczne jest skalowanie wartości (np. mnożenie przez 10) i rysowanie na bitmapie o wyższej rozdzielczości (np. TBitmap), a następnie skalowanie obrazu do formy. Podano przykład tworzenia i operowania na obiekcie TBitmap w Delphi, co pozwala na rysowanie z większą dokładnością. Zwrócono uwagę, że ostatecznie pozycje pikseli muszą być całkowite, a precyzję można uzyskać przez odpowiednie skalowanie i zaokrąglanie. Wskazano również, że dla małego zakresu argumentów (np. do 5 stopni) problem funkcji tangens jest ograniczony.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA