Ryan ma rację, to zdanie “względem punktów p i q” jest mylące. Ale zgaduję podobnie jak [alex], że chodzi Ci o współrzędne p i q wierzchołka paraboli. Generalnie trochę pogooglowałem i nie udało mi się znaleźć gotowej funkcji służącej do rysowania paraboli mając jako dane wierzchołek paraboli i jej miejsca zerowe. Naskrobałem natomiast taki kod (widoczny poniżej), który możesz sobie przetestować i zobaczyć, czy Ci to wystarczy (testowane przy użyciu free pascal, ale inne kompilatory też nie powinny mieć problemów z tym kodem).
program Parabola;
uses
crt, graph;
type
TPoint = record
X: double;
Y: double;
end;
TRoot = record
Point: TPoint;
IsDual: boolean;
IsValid: boolean;
end;
TRoots = array[1..2] of TRoot;
var
a,b,c,userXScale,userYScale: double;
myXScale,myYScale: integer;
roots: TRoots;
vertex: TPoint;
function FindRoots(a,b,c: double): TRoots;
var
delta: double;
roots: TRoots;
begin
roots[1].IsValid:= false;
roots[2].IsValid:= false;
delta:= sqr(b)-4*a*c;
if delta = 0 then begin
roots[1].Point.X:= (-b)/(2*a);
roots[1].Point.Y:= 0;
roots[1].IsDual:= true;
roots[1].IsValid:= true;
end else if delta > 0 then begin
roots[1].Point.X:= (-b-sqrt(delta))/(2*a);
roots[1].Point.Y:= 0;
roots[1].IsDual:= false;
roots[1].IsValid:= true;
roots[2].Point.X:= (-b+sqrt(delta))/(2*a);
roots[2].Point.Y:= 0;
roots[2].IsDual:= false;
roots[2].IsValid:= true;
end;
FindRoots:= roots;
end;
function FindVertex(a,b,c: double): TPoint;
var
vertex: TPoint;
begin
vertex.X:= (-b)/(2*a);
vertex.Y:= (-(sqr(b)-4*a*c))/(4*a);
FindVertex:= vertex;
end;
function FormatDoubleType(value: double): string;
var
result: string;
begin
Str(value:8:3,result);
FormatDoubleType:= result;
end;
procedure DisplayRoots(roots: TRoots);
begin
if roots[1].IsValid then begin
if roots[1].IsDual then begin
writeln('Dane rownanie kwadratowe posiada jeden pierwiastek podwojny o wspolrzednych:');
writeln('x = ',FormatDoubleType(roots[1].Point.X), ', y = ',FormatDoubleType(roots[1].Point.Y));
end else begin
writeln('Dane rownanie kwadratowe posiada dwa pierwiastki o wspolrzednych:');
writeln('x = ',FormatDoubleType(roots[1].Point.X), ', y = ',FormatDoubleType(roots[1].Point.Y));
writeln('x = ',FormatDoubleType(roots[2].Point.X), ', y = ',FormatDoubleType(roots[2].Point.Y));
end;
end else writeln('Dane rownanie kwadratowe nie posiada miejsc zerowych.');
writeln;
end;
procedure DisplayVertex(vertex: TPoint);
begin
writeln('Wierzcholek paraboli znajduje sie w punkcie o wspolrzednych:');
writeln('x = ',FormatDoubleType(vertex.X), ', y = ',FormatDoubleType(vertex.Y));
writeln;
end;
procedure InitializeGraph;
var
gd,gm : integer;
begin
DetectGraph(gd,gm);
InitGraph(gd,gm,'');
end;
procedure DrawLegend(a,b,c,userXScale,userYScale:double; myXScale,myYScale:integer);
var
i, value, halfMaxY, halfMaxX: integer;
begin
SetColor(white);
SetTextStyle(1, horizdir, 1);
halfMaxX:= GetMaxX div 2;
halfMaxY:= GetMaxY div 2;
OutTextXY(20, 20, 'f(x) = ' + FormatDoubleType(a) + '*x^2 + ' + FormatDoubleType(b) + '*x + ' + FormatDoubleType(c));
i:= 1;
value:= myXScale;
while value <= halfMaxX do
begin
Line(halfMaxX + value, halfMaxY - 10, halfMaxX + value, halfMaxY + 10);
OutTextXY(halfMaxX + (i-1)*myXScale, halfMaxY + 20, FormatDoubleType(userXScale*i));
Line(halfMaxX - value, halfMaxY - 10, halfMaxX - value, halfMaxY + 10);
OutTextXY(halfMaxX - value, halfMaxY + 20, FormatDoubleType(-(userXScale*i)));
i:= i+1;
value:=i*myXScale;
end;
i:= 1;
value:= myYScale;
while value <= halfMaxY do
begin
Line(halfMaxX - 10, halfMaxY + value, halfMaxX + 10, halfMaxY + value);
OutTextXY(halfMaxX + 20, halfMaxY + value, FormatDoubleType(-(userYScale*i)));
Line(halfMaxX - 10, halfMaxY - value, halfMaxX + 10, halfMaxY - value);
OutTextXY(halfMaxX + 20, halfMaxY - value, FormatDoubleType(userYScale*i));
i:= i+1;
value:=i*myYScale;
end;
end;
procedure DrawXYAxis;
begin
SetColor(white);
Line(0, GetMaxY div 2, GetMaxX, GetMaxY div 2);
Line(GetMaxX div 2, 0, GetMaxX div 2, GetMaxY);
end;
procedure DrawParabola(a,b,c,userXScale,userYScale:double; myXScale,myYScale:integer);
var
x, y, previousX, previousY, halfMaxY, halfMaxX: integer;
xParabola, yParabola, scaleX, scaleY: double;
begin
SetColor(red);
scaleX:= userXScale/myXScale;
scaleY:= userYScale/myYScale;
halfMaxX:= GetMaxX div 2;
halfMaxY:= GetMaxY div 2;
previousX:= 0;
previousY:= 0;
y:= 0;
for x:= 0 to GetMaxX do
begin
xParabola:= (x-halfMaxX)*scaleX;
yParabola:= a*sqr(xParabola)+b*xParabola+c;
if (ABS(yParabola/scaleY) + halfMaxY) < MaxInt then begin
if yParabola < 0 then y:= ABS(ROUND(yParabola/scaleY)) + halfMaxY
else y:= halfMaxY - ROUND(yParabola/scaleY);
if (y >= 0) and (y <= GetMaxY) then begin
if (previousX <> 0) and (previousY <> 0) then Line(previousX, previousY, x, y);
previousX:= x;
previousY:= y;
end else begin
previousX:= 0;
previousY:= 0;
end;
end;
end;
end;
begin
ClrScr;
writeln('Podaj wspolczynniki rownania kwadratowego:');
write('a: '); readln(a);
write('b: '); readln(b);
write('c: '); readln(c);
writeln;
writeln('Podaj skale wykresu:');
write('dla osi X: '); readln(userXScale); myXScale:= 70;
write('dla osi Y: '); readln(userYScale); myYScale:= 70;
writeln;
roots:= FindRoots(a,b,c);
DisplayRoots(roots);
vertex:= FindVertex(a,b,c);
DisplayVertex(vertex);
InitializeGraph;
DrawLegend(a,b,c,userXScale,userYScale,myXScale,myYScale);
DrawXYAxis;
DrawParabola(a,b,c,userXScale,userYScale,myXScale,myYScale);
readkey; CloseGraph;
end.
– Dodane 01.06.2011 (Śr) 23:15 –
Wprowadziłem drobne zmiany w programie. Teraz można podawać skalę osi X i Y. Takie rozwiązanie przydaje się, przy niektórych parabolach, dla których np. p jest bardzo małe, a q bardzo duże. Można też pomyśleć, aby ten program przerobić tak, żeby sam ustalał skalę osi X i Y (automatycznie).
Przykładowe dane, dla których ładnie to widać, to:
a,b i c = 65
skala osi X = 0.5
skala osi Y = 50