[Pascal]zadanie matematyczno-graficzne

0

WItam!

siedze na tym programem juz od dawien dawna i nie moge zrobic nic, zeby poprawnie dzialal... moze ktos z was bedzie potrafil mi pomoc...

sprawa wyglada tak:

trzeba zebrac 2 dane na poczatku: ilosc bokow wielokata i dlugosc promienia

w trybie graficznym trzeba namalowac wielokat o podanej LICZBIE BOKOW, po srodku ekranu (getmaxx div 2, getmaxy div 2 zeby bylo jasne :))... KAzdy wierzcholek ma byc odlegly od srodka o PROMIEN.....

z tego co mi wiadomo trzeba uzyc wzoru na wspolrzedne biegunowe, takie cos to jest, ze wspolrzedne wiercholka x to prmien*cos (alfa) a y to sin alfa....

potrafi mi ktos pomoc....?

0

widze, że nie znasz wzorów na okręg:
<font color="blue">x= cos(alfa)*r
y= sin(alfa)*r</span>

czasami musisz alfa podać w radianach - pamiętaj, że 2PI to 360 stopni, czyli żeby zamienić stopnie na radiany mnożysz alfa przez PI/180 = 0,0174533

wyznaczenie wierzchołków nie powinno ci sprawić teraz trudności...

jeżeli mieżysz w stopniach to w pętli wyznaczasz wierzchołki:
x i y to tablice typu real

for i:=1 to n do
begin
   x[i]:= cos(360/n)*r;
   y[i]:= sin(360/n)*r;
end;

x[i] i y[i] to współrzędne względem środka okręgu czyli musisz do nich dodać odpowiednie wsp (te co podałeś w swoim poście), żeby narysować koło na środku ekranu...
potem musisz tylko poszukać funkcji rysującej dowolną linię i gotowe (no prawie) ...

PS. Jeżeli ten opis Ci nie pomaga, to poszukaj źródeł w necie...

0

jezeli chodiz o teorie to chyba wiem jak to zrobic, niestety gorzej z praktyka...

jakby ktos mial czas napisac od momentu przejscia w tryb graficzny kodzik...

0

OK, masz tutaj kod, ale w Delphi, mam nadzieje, że to nie jest dla Ciebie zbyt wielką przeszkodą.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var r,i,ilosc_bokow:integer;
    alfa:real;
    x,y, xs,ys:integer;
begin
     //polozenie punktow obliczane jest ze wzoru
     // x=r*cos(alfa) , y=r*sin(alfa)
    ilosc_bokow:=strtoint(edit1.text);
    r:=strtoint(edit2.Text);
    alfa:=((2*pi)/ilosc_bokow);  //okreslenie kata alfa w radianach
    xs:=form1.Width div 2;    //srodek formularza
    ys:=form1.Height div 2;   //srodek formularza
    form1.Canvas.MoveTo(xs+r,ys);   //ustalenie pedzla na srodku formularza
    form1.Canvas.Pen.color:=clred;  //rysowanie na czerwono

         for i:=0 to ilosc_bokow do
         begin
             x:=round(xs+r*cos(i*alfa));    //obliczanie wspolrzednych
             y:=round(ys+r*sin(i*alfa));
             form1.Canvas.LineTo(x,y);     //rysowanie lini od punktu do punktu
         end;

end;

end.

Wstaw na forme dwa edity i jeden button. Powinno zadziałać

0

W zasadzie zgadam się z przedmówcą ale muszę tu zamieścić jedną uwagę

 for i:=0 to ilosc_bokow do
         begin
             x:=round(xs+r*cos(i*alfa));    //obliczanie wspolrzednych
             y:=round(ys+r*sin(i*alfa));
             form1.Canvas.LineTo(x,y);     //rysowanie lini od punktu do punktu
         end;

a wcześniej było

  form1.Canvas.MoveTo(xs+r,ys);

I być może się czepiam ale:

Jeżeli w pętli weźmiemy i=0 to
x=round(xs+rcos0)=round(xs+r1)=xs+r
y=round(ys+rsin0)=round(ys+r0)=ys
zatem w instrukcji LineTo będziemy mieli że linia ma być narysowana od punktu o współrzędnych (xs+r,ys) do punktu o tych samych współrzędnych, czyli w efekcie nic nie narysuje. Zatem ten jeden obieg pętli nie jest potrzebny.
Reasumując pętla powinna wyglądać

for i:=1 to ilosc_bokow do
     begin
         ...
    end
0

spox, dzieki wszystkim....
zaraz zobacze czy zadziala :)

0

niestety....

mam taki kod i niestety nie dziala poprawnie...

alfa:=round((2*Pi)/ilosc_bokow);
x0:=getmaxx div 2;
y0:=getmaxy div 2;

moveto(x0,y0);
for koniec:=1 to ilosc_bokow do
       begin
              x:=x0+promien*koniec*cos(koniec*alfa);
              y:=y0+promien*koniec*sin(koniec*alfa);
              lineto(round(x), round(y));
       end;
       readln;
closegraph;
end.

cos sie rysuje, ale nie tak jak powinno byc, tzn nie ma nic wspolnego z wielokatem....

widzi ktos blad?

// istnieje takie coś jak tag delphi - detox

0

nie rozumiem... o co chodzi z tagiem delphi..>? chodzi mi tu o Turbo Pascala, delphi nigdy sie nie uczylem...

// delphi to tag - jak piszesz posta u góry masz przyciski - jeśli piszesz jakiś kod w delphi / pascal to umieszczaj go w tym tagu - to tyle... - detox

0

Moim zdanie powinno być tak

       for koniec:=1 to ilosc_bokow do
       begin
              x:=round(x0+promien*cos(koniec*alfa));
              y:=round(y0+promien*sin(koniec*alfa));
              lineto(round(x), round(y));
       end;
0

jest tak juz i niestety nadal nie dziala poprawnie...

tzn... 5 kat wyglada tak jak w linku:

user image

0

Na początku, zamiast

MoveTo(x0,y0);

napisz MoveTo(round(x0+promiencos(0)), y0+promiensin(0)));

Powinno zadziałać.
0

Sorki, ale zamiast

 for koniec:=1 to ilosc_bokow do 
   ...

powinno byc

 for koniec:=0 to ilosc_bokow do
   ...
0
alfa:=round((2*Pi)/ilosc_bokow);
x0:=getmaxx div 2;
y0:=getmaxy div 2;

moceto(round(x0+promien*cos(0)), round(y0+promien*sin(0))); 

for koniec:=0 to ilosc_bokow do
       begin
              x:=x0+promien*koniec*cos(koniec*alfa);
              y:=y0+promien*koniec*sin(koniec*alfa);
              lineto(round(x), round(y));
       end;
       readln;
closegraph;
end. 

caly czas cos sie wali z katem chyba... bo niezaleznie od tego jakie dam ilosc bokow to kat jest ten sam...

0
alfa:=(2*Pi)/ilosc_bokow;
x0:=getmaxx div 2;
y0:=getmaxy div 2;

moveto(round(x0+promien*cos(0)), round(y0+promien*sin(0))); 

for koniec:=1 to ilosc_bokow do
       begin
              x:=x0+promien*cos(koniec*alfa);
              y:=y0+promien*sin(koniec*alfa);

// x:=x0+promien*konieccos(koniecalfa);
// y:=y0+promien*koniecsin(koniecalfa); tu byl blad

              lineto(round(x), round(y));
       end;
       readln;
closegraph;
end. 

alpha powinna byc double

mi taki kod dziala

0

http://www.jtazeroth2.neostrada.pl/WIELKOKA.PAS

tutaj daje link do mojego programu... zrobilem chyab dokladnie tak jak napisales zd ci dziala... u mnie cos sie wali caly czas... moze ktos rzucic okiem ?

0
program wielokaty; 
uses crt, graph; 

var ilosc_bokow, promien, koniec:integer; 
var x,y,alfa:real; {grafika} 
var tryb, sterownik, x0, y0:integer; 

label boki; 
label promyk; 

begin 

boki:; 
ClrScr; 
Write('Podaj ilosc bokow, ktore ma miec przyszly wielokat: '); 
Readln(ilosc_bokow); 

if (ilosc_bokow<3) then 
begin 
writeln('BLAD !!! Musza byc conajmniej 3 boki'); 
delay(500); 
goto boki; 
end; 

promyk:; 
Write('Podaj dlugosc promienia wodzacego: '); 
Readln(promien); 
if (promien<2) then begin writeln('BLAD !!! Promien za krotki'); 
writeln(''); 
delay(500); 
goto promyk; 
end; 

detectgraph(tryb,sterownik); 

initgraph(tryb,sterownik,'h:\BGI'); 

alfa:=(2*Pi)/ilosc_bokow; 
x0:=getmaxx div 2; 
y0:=getmaxy div 2; 

moveto(round(x0+promien*cos(0)),round(y0+promien*sin(0))); 

for koniec:=1 to ilosc_bokow do 

begin 

x:=x0+promien*koniec*cos(koniec*alfa); 
y:=y0+promien*koniec*sin(koniec*alfa); 

lineto(round(x),round(y)); 
end; 
readln; 
closegraph; 
end.

cos sie jednak wali i nie mozna sciagnac go dobrze... przepisalem go w miare ladniej...

rozwiazane juz

0

:D
Już pare osób to podkreślało, zamiast

for koniec:=1 to ilosc_bokow do 

begin 

x:=x0+promien*koniec*cos(koniec*alfa); 
y:=y0+promien*koniec*sin(koniec*alfa); 

lineto(round(x),round(y)); 
end; 

wpisz

for koniec:=0 to ilosc_bokow do 

begin 

x:=x0+promien*cos(koniec*alfa); 
y:=y0+promien*sin(koniec*alfa); 

lineto(round(x),round(y)); 
end; 

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