Jak narysować sześcian na formatce?

0

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 ;<

0

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.

2

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.

0

chodziło by mi o zwykły sześcian, bez udziwnień :D wlaśnie próbuje coś canvasami zrobć ale mozolnie mi to idzie

2

bbe229cd8e.png

  1. Oblicz sobie punkty zaznaczone czerwonym.
  2. Znajdź: Mx=min(Points[i].x) i My=min(Points[i].y)
  3. Odejmij od każdej współrzędnej Mx, My
  4. Znajdź: Mx=max(Points[i].x) i My=max(Points[i].y) dla już przeliczonych punktów.
  5. Wylicz zoom=min(MaxBoxWidth/Mx,MaxBoxHeight/My)
  6. Przelicz każdą współrzędną Points[i].x=Margin+Points[i].x*zoom oraz Points[i].y=Margin+Points[i].y*zoom
0

_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?:)

0
  1. Nic ci nie da ściągnięcie punktów z CAD'a ponieważ punkty trzeba wyliczyć dla konkretnych podanych H, B, L
  2. Mx/My obliczane są ze wszystkich wyliczonych punktów
0

To z moją wiedzą bardziej możliwe będzie wykonanie Canvasami, ale dzięki za podpowiedź ;)

0

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.

0

nie wiem jaką wersję delphi posiadasz ale w firemonkey robisz coś takiego bez linijki kodu ;)

0

delphi 7, mozesz przybliżyc Twoja wersje?

2

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

0

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!'); 
2

Pewnie dlatego Ci się wywala bo X i Y powinny być liczbami całkowitymi.

1

@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;
0

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) ?:)

1

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.

0

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.

0

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;

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