Witam, jestem bardzo poczatkujący w progrmowaniu, mam do napisania pewien kalkulator obliczający wytrzymałość, mam już prawie całość ale chce aby bardziej 'cieszył oko' i wpadłem na pomysł by po wprowadzeniu wartosci (Długość szerokość i wysokość) rysował sześcian, ale aby tez miał pewne zabezpieczenia w sensie aby się skalował w stosunku do wymiarów okienka gdzie będzie wyświetlany. Póki co wkleiłem chamsko zdjęcie, mam nadzieję, ze ktos naprowadzi mnie jak to zrobić, funkcją Canvas? tylko jak ;<
No sześcianu nie 'wstawiłeś' tylko otwarty karton?
myślę że sześcian Canvasem dasz radę narysować w miarę szybko, poszuka przykładów w sieci, co do 'otwartego pudła' to już więcej rzeźbienia.
Najprościej będzie narysować sześcian w takiej formie:
http://www.matmana6.pl/zdjecia/szkola_srednia/geometria_w_przestrzeni_stereometria/szescian_39.png
Szerokość i wysokość po prostu skalujesz, natomiast głębokość może być przekładana na przesunięcie po skosie w górę i w prawo, współczynniki dobierz sam, żeby wyglądało naturalnie. Najlepiej oblicz położenie wszystkich punktów sześcianu na płaszczyźnie uwzględniając przesunięcie w głąb jako przesunięcie na ukos. Wtedy łatwo będzie obliczyć wysokość i szerokość całego rysunku, a mając wymiary rysunku i wymiary pola przewidzianego na ten rysunek obliczysz współczynnik, przez który pomnożysz współrzędne każdego z punktów rysunku, co spowoduje jego zmniejszenie lub powiększenie, żeby zmieścił się w polu przewidzianym na ten rysunek.
Oczywiście przy użyciu TBitmap.Canvas, jednak przypominam, że to powinno być na osobnym obiekcie typu TBitmap, który będzie wyświetlany. Jak będziesz rysować bezpośrednio na formatce, to rysunek będzie ulotny, zniknie po zminimalizowaniu lub zasłonięciu okna aplikacji.
chodziło by mi o zwykły sześcian, bez udziwnień :D wlaśnie próbuje coś canvasami zrobć ale mozolnie mi to idzie
- Oblicz sobie punkty zaznaczone czerwonym.
- Znajdź:
Mx=min(Points[i].x)
iMy=min(Points[i].y)
- Odejmij od każdej współrzędnej
Mx
,My
- Znajdź:
Mx=max(Points[i].x)
iMy=max(Points[i].y)
dla już przeliczonych punktów. - Wylicz
zoom=min(MaxBoxWidth/Mx,MaxBoxHeight/My)
- Przelicz każdą współrzędną
Points[i].x=Margin+Points[i].x*zoom
orazPoints[i].y=Margin+Points[i].y*zoom
_13th_Dragon - brak obrazka ;)
Edit.1
Podoba mi się Twój pomysł, bo mogę swtorzyć coś jeszcze lepszego ;)Przy pomocy CAD'a ściągnąłem punkty, i wyglada to jak na zdjęciu (wartosci mogę odczytac bez problemu) tylko nie bardzo wiem co oznaczają Mx i My
Znajdź: Mx=min(Points[i].x) i My=min(Points[i].y)
Odejmij od każdej współrzędnej Mx, My
mając wartości x,y (punkty) jak je wkleić do kodu aby to sie narysowało?:)
- Nic ci nie da ściągnięcie punktów z CAD'a ponieważ punkty trzeba wyliczyć dla konkretnych podanych
H
,B
,L
- Mx/My obliczane są ze wszystkich wyliczonych punktów
To z moją wiedzą bardziej możliwe będzie wykonanie Canvasami, ale dzięki za podpowiedź ;)
No właśnie po tym co napisałem to rysujesz za pomocą Canvas.Polygon
: http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.Graphics.TCanvas.Polygon
Algorytm podałem na obliczenie skalowania, tak aby się zmieściło w wyznaczonym obszarze.
nie wiem jaką wersję delphi posiadasz ale w firemonkey robisz coś takiego bez linijki kodu ;)
delphi 7, mozesz przybliżyc Twoja wersje?
Firemonkey jest narzedziem dla nowszych Delphi w wersji XE.
Możesz sobie ściągnąć wersje trial 30 dniową delphi XE7. I pewnie w jeden dzień napiszesz sobie ten swój programik (zresztą pewnie bezproblemu zaimportujesz z delphi 7 do delphi xe7 swoj projekt). pozdro
zmagałem się cały dzień i nic :D jako, że dopiero się uczę delphi próbowałem zacząć od prostego prostokąta który się narysuje po wprowadzeniu danych z Edit1 i Edit 2
ale niestety funkja Canvas.Rectangle (0,0,x,y); nie pozwala wpisać x,y
oto moj kod, co powinnienem zmienić albo jak szukać rozwiązania?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
Edit1: TEdit;
Edit2: TEdit;
function StrIsReal(AString: string): Boolean;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
x: double;
y: double;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TForm1.StrIsReal(AString: string): Boolean;
var
I: Extended;
Code: Integer;
begin
Val(AString, I, Code);
Result := Code = 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var x,y: extended;
success: boolean;
begin
if StrIsReal(Edit1.Text) then
x:= StrToFloat(Edit1.Text);
if StrIsReal(Edit2.Text) then
y:= StrToFloat(Edit2.Text);
if (StrIsReal(Edit1.Text)) and (StrIsReal(Edit2.Text)) then
success := true
else
success := false;
if success = true then
** Image1.Canvas.Rectangle(0, 0, X , Y)**
else
ShowMessage('ZŁY ZNAK!');
Pewnie dlatego Ci się wywala bo X i Y powinny być liczbami całkowitymi.
@daro1337 - już lepiej tak:
procedure TForm1.Button1Click(Sender: TObject);
var
X, Y: Extended;
begin
if (StrIsReal(Edit1.Text)) and (StrIsReal(Edit2.Text)) then
begin
X := StrToFloat(Edit1.Text);
Y := StrToFloat(Edit2.Text);
Image1.Canvas.Rectangle(0, 0, Round(X) , Round(Y))
end
else
ShowMessage('ZŁY ZNAK!');
end;
Funkcja Round zwraca zaokrągloną liczbę całkowitą, więc ją można już użyć w tej metodzie; Pamietaj, że wszystkie metody klasy TCanvas
operują na liczbach całkowitych;
PS: Albo w ten sposób:
procedure TForm1.Button1Click(Sender: TObject);
var
X, Y: Extended;
begin
if TryStrToFloat(Edit1.Text, X) and TryStrToFloat(Edit2.Text) then
Image1.Canvas.Rectangle(0, 0, Round(X) , Round(Y))
else
ShowMessage('ZŁY ZNAK!');
end;
furious programming WIELKIE dzięki :D teraz działa jak należym zaraz sobie przeanalizuje i wyciągnę wnioski;)
czy tak smao mogę robić z funkcją LineTo (x,y) ?:)
Dokładnie jak napisał poprzednik. Przecież samo Delphi Tobie podpowiada, jakie są parametry, gdy tylko zaczniesz pisać Canvas.Rectangle(
. Poza tym nie potrzebujesz funkcji osobnej do sprawdzania poprawności liczb. Istnieją już w module SysUtils
przecież TryStrToInt
albo TryStrToFloat
.
Zaś zmienną Success
można połączyć pisząc Success := (Warunek1) and (Warunek2);
. A i do tego polecam sobie wyrobić nawyk, by nie stosować konstrukcji if ... = True then
, tylko pisać od razu if Warunek then
jeśli prawda lub if not Watunek then
jeśli sprawdzasz czy fałsz.
czy tak smao mogę robić z funkcją LineTo (x,y) ?:)
Tak, możesz z metodą LineTo
i z każdą inną, która przyjmuje całkowitoliczbowe argumenty.
chyba porzucę ten projekt może jakiemuś innemu początkującego się przyda co stworzyłem - rysuje ' szescian' ale wyswietlago w miarę poprawnie gdy x=y w innych przypadkach się rozjezdza , pewnie dałoby rade mnożąc współczynniki odpowiednie wyprowadzić to jakoś ale to już nie na moje sily:D
procedure TForm1.Button1Click(Sender: TObject);
var
X, Y, Z: Extended;
begin
Image1.canvas.rectangle(0, 0, width, height);
if TryStrToFloat(Edit1.Text, X) and TryStrToFloat(Edit2.Text, y) and TryStrToFloat(Edit3.Text, z) then
Image1.Canvas.MoveTo (200,200); //poczatek
Image1.Canvas.LineTo(Round(200+X) , Round(200)); //prawy dolny rog
Image1.Canvas.LineTo( Round(200+X), Round(200-Y)); // prawy górny róg
Image1.Canvas.LineTo( Round(200), Round(200-Y)); // lewy górny
Image1.Canvas.LineTo( 200, 200) ; //początek(zakonczenie)
Image1.Canvas.MoveTo(Round(200+X) , Round(200-Y)); //prawy gorny Róg
Image1.Canvas.LineTo(Round(200+X+Z), Round(200-Y-Z));
Image1.Canvas.LineTo(Round(200+X), Round(200-Y-Z));
Image1.Canvas.LineTo( Round(200), Round(200-Y));
Image1.canvas.Moveto(Round(200+X) , Round(200));
Image1.Canvas.Lineto(Round(200+X+Z), Round(200-Z));
Image1.Canvas.LineTo(Round (200+X+Z), Round(200-y-z));
end;