program EulerMethod;
uses
SysUtils, Math;
const
g = 9.81;
k = 0.1;
tau = 0.01;
t_max = 10.0;
GRAPH_WIDTH = 80;
GRAPH_HEIGHT = 24;
var
t, x, y, vx, vy: Double;
vx_prev, vy_prev, v: Double;
maxX, maxY: Double;
graph: array of array of Char;
i, j: Integer;
procedure InitializeGraph;
begin
SetLength(graph, GRAPH_HEIGHT);
for i := 0 to GRAPH_HEIGHT - 1 do
begin
SetLength(graph[i], GRAPH_WIDTH);
for j := 0 to GRAPH_WIDTH - 1 do
graph[i][j] := ' ';
end;
end;
procedure PlotPoint(xVal, yVal: Double);
var
xPos, yPos: Integer;
begin
if (maxX > 0) and (maxY > 0) then
begin
xPos := Round((xVal / maxX) * (GRAPH_WIDTH - 1));
yPos := GRAPH_HEIGHT - 1 - Round((yVal / maxY) * (GRAPH_HEIGHT - 1));
if (xPos >= 0) and (xPos < GRAPH_WIDTH) and
(yPos >= 0) and (yPos < GRAPH_HEIGHT) then
graph[yPos][xPos] := '*';
end;
end;
procedure DrawGraph;
var
i, j: Integer;
begin
for i := 0 to GRAPH_HEIGHT - 1 do
begin
for j := 0 to GRAPH_WIDTH - 1 do
Write(graph[i][j]);
WriteLn;
end;
end;
begin
InitializeGraph;
maxX := 0;
maxY := 0;
t := 0.0;
x := 0.0;
y := 0.0;
vx := 10.0;
vy := 20.0;
WriteLn('t':10, 'x':15, 'y':15, 'vx':15, 'vy':15);
WriteLn(Format('%10.3f %14.3f %14.3f %14.3f %14.3f', [t, x, y, vx, vy]));
// First pass to determine max values
while t < t_max do
begin
vx_prev := vx;
vy_prev := vy;
v := Sqrt(vx_prev * vx_prev + vy_prev * vy_prev);
vx := vx_prev + (-k * v * vx_prev) * tau;
vy := vy_prev + (-g - k * v * vy_prev) * tau;
x := x + vx_prev * tau;
y := y + vy_prev * tau;
t := t + tau;
if x > maxX then maxX := x;
if y > maxY then maxY := y;
if y <= 0 then
Break;
end;
// Add 10% padding
maxX := maxX * 1.1;
maxY := maxY * 1.1;
// Reset for second pass
t := 0.0;
x := 0.0;
y := 0.0;
vx := 10.0;
vy := 20.0;
// Second pass to plot points
while t < t_max do
begin
vx_prev := vx;
vy_prev := vy;
v := Sqrt(vx_prev * vx_prev + vy_prev * vy_prev);
vx := vx_prev + (-k * v * vx_prev) * tau;
vy := vy_prev + (-g - k * v * vy_prev) * tau;
x := x + vx_prev * tau;
y := y + vy_prev * tau;
t := t + tau;
PlotPoint(x, y);
WriteLn(Format('%10.3f %14.3f %14.3f %14.3f %14.3f', [t, x, y, vx, vy]));
if y <= 0 then
Break;
end;
WriteLn;
WriteLn('Trajectory Graph:');
WriteLn('Y');
WriteLn('↑');
DrawGraph;
WriteLn('0', StringOfChar('-', GRAPH_WIDTH - 1), '→ X');
WriteLn('Max X: ', maxX:0:2, ' Max Y: ', maxY:0:2);
WriteLn('Press Enter to exit...');
ReadLn;
end.
cHJvZ3JhbSBFdWxlck1ldGhvZDsKCnVzZXMKICBTeXNVdGlscywgTWF0aDsKCmNvbnN0CiAgZyA9IDkuODE7ICAgICAgICAgCiAgayA9IDAuMTsgICAgICAgICAgCiAgdGF1ID0gMC4wMTsgICAgIAogIHRfbWF4ID0gMTAuMDsgICAgICAgCiAgR1JBUEhfV0lEVEggPSA4MDsKICBHUkFQSF9IRUlHSFQgPSAyNDsKCnZhcgogIHQsIHgsIHksIHZ4LCB2eTogRG91YmxlOwogIHZ4X3ByZXYsIHZ5X3ByZXYsIHY6IERvdWJsZTsKICBtYXhYLCBtYXhZOiBEb3VibGU7CiAgZ3JhcGg6IGFycmF5IG9mIGFycmF5IG9mIENoYXI7CiAgaSwgajogSW50ZWdlcjsKCnByb2NlZHVyZSBJbml0aWFsaXplR3JhcGg7CmJlZ2luCiAgU2V0TGVuZ3RoKGdyYXBoLCBHUkFQSF9IRUlHSFQpOwogIGZvciBpIDo9IDAgdG8gR1JBUEhfSEVJR0hUIC0gMSBkbwogIGJlZ2luCiAgICBTZXRMZW5ndGgoZ3JhcGhbaV0sIEdSQVBIX1dJRFRIKTsKICAgIGZvciBqIDo9IDAgdG8gR1JBUEhfV0lEVEggLSAxIGRvCiAgICAgIGdyYXBoW2ldW2pdIDo9ICcgJzsKICBlbmQ7CmVuZDsKCnByb2NlZHVyZSBQbG90UG9pbnQoeFZhbCwgeVZhbDogRG91YmxlKTsKdmFyCiAgeFBvcywgeVBvczogSW50ZWdlcjsKYmVnaW4KICBpZiAobWF4WCA+IDApIGFuZCAobWF4WSA+IDApIHRoZW4KICBiZWdpbgogICAgeFBvcyA6PSBSb3VuZCgoeFZhbCAvIG1heFgpICogKEdSQVBIX1dJRFRIIC0gMSkpOwogICAgeVBvcyA6PSBHUkFQSF9IRUlHSFQgLSAxIC0gUm91bmQoKHlWYWwgLyBtYXhZKSAqIChHUkFQSF9IRUlHSFQgLSAxKSk7CiAgICBpZiAoeFBvcyA+PSAwKSBhbmQgKHhQb3MgPCBHUkFQSF9XSURUSCkgYW5kCiAgICAgICAoeVBvcyA+PSAwKSBhbmQgKHlQb3MgPCBHUkFQSF9IRUlHSFQpIHRoZW4KICAgICAgZ3JhcGhbeVBvc11beFBvc10gOj0gJyonOwogIGVuZDsKZW5kOwoKcHJvY2VkdXJlIERyYXdHcmFwaDsKdmFyCiAgaSwgajogSW50ZWdlcjsKYmVnaW4KICBmb3IgaSA6PSAwIHRvIEdSQVBIX0hFSUdIVCAtIDEgZG8KICBiZWdpbgogICAgZm9yIGogOj0gMCB0byBHUkFQSF9XSURUSCAtIDEgZG8KICAgICAgV3JpdGUoZ3JhcGhbaV1bal0pOwogICAgV3JpdGVMbjsKICBlbmQ7CmVuZDsKCmJlZ2luCiAgSW5pdGlhbGl6ZUdyYXBoOwogIG1heFggOj0gMDsKICBtYXhZIDo9IDA7CgogIHQgOj0gMC4wOwogIHggOj0gMC4wOwogIHkgOj0gMC4wOwogIHZ4IDo9IDEwLjA7ICAgICAgCiAgdnkgOj0gMjAuMDsgICAgIAoKICBXcml0ZUxuKCd0JzoxMCwgJ3gnOjE1LCAneSc6MTUsICd2eCc6MTUsICd2eSc6MTUpOwogIFdyaXRlTG4oRm9ybWF0KCclMTAuM2YgJTE0LjNmICUxNC4zZiAlMTQuM2YgJTE0LjNmJywgW3QsIHgsIHksIHZ4LCB2eV0pKTsKCiAgLy8gRmlyc3QgcGFzcyB0byBkZXRlcm1pbmUgbWF4IHZhbHVlcwogIHdoaWxlIHQgPCB0X21heCBkbwogIGJlZ2luCiAgICB2eF9wcmV2IDo9IHZ4OwogICAgdnlfcHJldiA6PSB2eTsKCiAgICB2IDo9IFNxcnQodnhfcHJldiAqIHZ4X3ByZXYgKyB2eV9wcmV2ICogdnlfcHJldik7CgogICAgdnggOj0gdnhfcHJldiArICgtayAqIHYgKiB2eF9wcmV2KSAqIHRhdTsKICAgIHZ5IDo9IHZ5X3ByZXYgKyAoLWcgLSBrICogdiAqIHZ5X3ByZXYpICogdGF1OwoKICAgIHggOj0geCArIHZ4X3ByZXYgKiB0YXU7CiAgICB5IDo9IHkgKyB2eV9wcmV2ICogdGF1OwoKICAgIHQgOj0gdCArIHRhdTsKCiAgICBpZiB4ID4gbWF4WCB0aGVuIG1heFggOj0geDsKICAgIGlmIHkgPiBtYXhZIHRoZW4gbWF4WSA6PSB5OwoKICAgIGlmIHkgPD0gMCB0aGVuCiAgICAgIEJyZWFrOwogIGVuZDsKCiAgLy8gQWRkIDEwJSBwYWRkaW5nCiAgbWF4WCA6PSBtYXhYICogMS4xOwogIG1heFkgOj0gbWF4WSAqIDEuMTsKCiAgLy8gUmVzZXQgZm9yIHNlY29uZCBwYXNzCiAgdCA6PSAwLjA7CiAgeCA6PSAwLjA7CiAgeSA6PSAwLjA7CiAgdnggOj0gMTAuMDsgICAgICAKICB2eSA6PSAyMC4wOyAgICAgCgogIC8vIFNlY29uZCBwYXNzIHRvIHBsb3QgcG9pbnRzCiAgd2hpbGUgdCA8IHRfbWF4IGRvCiAgYmVnaW4KICAgIHZ4X3ByZXYgOj0gdng7CiAgICB2eV9wcmV2IDo9IHZ5OwoKICAgIHYgOj0gU3FydCh2eF9wcmV2ICogdnhfcHJldiArIHZ5X3ByZXYgKiB2eV9wcmV2KTsKCiAgICB2eCA6PSB2eF9wcmV2ICsgKC1rICogdiAqIHZ4X3ByZXYpICogdGF1OwogICAgdnkgOj0gdnlfcHJldiArICgtZyAtIGsgKiB2ICogdnlfcHJldikgKiB0YXU7CgogICAgeCA6PSB4ICsgdnhfcHJldiAqIHRhdTsKICAgIHkgOj0geSArIHZ5X3ByZXYgKiB0YXU7CgogICAgdCA6PSB0ICsgdGF1OwoKICAgIFBsb3RQb2ludCh4LCB5KTsKICAgIFdyaXRlTG4oRm9ybWF0KCclMTAuM2YgJTE0LjNmICUxNC4zZiAlMTQuM2YgJTE0LjNmJywgW3QsIHgsIHksIHZ4LCB2eV0pKTsKCiAgICBpZiB5IDw9IDAgdGhlbgogICAgICBCcmVhazsKICBlbmQ7CgogIFdyaXRlTG47CiAgV3JpdGVMbignVHJhamVjdG9yeSBHcmFwaDonKTsKICBXcml0ZUxuKCdZJyk7CiAgV3JpdGVMbign4oaRJyk7CiAgRHJhd0dyYXBoOwogIFdyaXRlTG4oJzAnLCBTdHJpbmdPZkNoYXIoJy0nLCBHUkFQSF9XSURUSCAtIDEpLCAn4oaSIFgnKTsKICBXcml0ZUxuKCdNYXggWDogJywgbWF4WDowOjIsICcgIE1heCBZOiAnLCBtYXhZOjA6Mik7CgogIFdyaXRlTG4oJ1ByZXNzIEVudGVyIHRvIGV4aXQuLi4nKTsKICBSZWFkTG47CmVuZC4=