The problem with using the Procedure in Pascal - pascal

uses GraphABC;
var
x, y, a: integer;
procedure treug(x, y, a, b: integer);
begin
x := 0;
y := 20;
line(x, y, x+a, y);
line(x, y, x, y+b);
line(x+a, y, x, y+b);
end;
begin
writeln('Enter the length of the catheter');
read(a);
while y < 480 do
begin
y := y+1;
treug(x, y, a, a);
end;
end.
Outputs only one triangle, and not the desired number up to the vertical border.
I expected one vertical row of right triangles (x and y are the coordinates of the right angle) to the lower border of the graphic window.

uses GraphABC;
var
x, y, a: integer;
procedure treug(x, y, a, b: integer);
begin
line(x, y, x+a, y);
line(x, y, x, y+b);
line(x+a, y, x, y+b);
end;
begin
writeln('Enter the length of the catheter');
read(a);
x := 0; // <-- initialize your x and y here
y := 20;
while y < 480 do
begin
y := y+1; // (see note below)
treug(x, y, a, a);
end;
end.
Remember, you have two sets x and y variables:
The global ones declared in the main program (and now properly initialized in the main program)
The ones local to the treug() procedure.
Things may have the same name and not be the same thing. If it helps, you can think of the global x as GraphABC.x and the local x as GraphABC.treug.x.
BTW, you probably want to increment y by something more than 1 each time through the loop, otherwise it’ll look just like a single triangle has been smeared down the display. (You might want to increment by b.)

Related

How to fill the graphic window?

uses GraphABC;
var
x, y: integer;
procedure kv(x, y: integer; color: system.Drawing.Color);
begin
Rectangle(x, y, x + 20, y - 50);
FloodFill(x + 10, y - 10, color);
end;
procedure radpiramid;
begin
x := 80;
while x < 640 do
begin
SetPenColor(clBlack);
kv(x - 40, 50, clGreen);
y := 100;
for var i := 1 to 3 do
kv(x - 20 * i, y, clOrange);
y := 150;
for var i := 1 to 5 do
kv(x + 40 - 20 * (i + 1), y, clRed);
x := x + 105;
end
end;
begin
while y <= windowHeight do
begin
radpiramid;
end;
end.
How to extend a series of pyramids to the entire window? I enter the values of x and y in the last block, but this does not affect anything.
Inside the radpiramid procedure and kv procedure you using a fixed value of y.
procedure kv(x, y: integer; color: system.Drawing.Color);
...
Rectangle(x, y, x + 20, y - 50); <----------------
...
procedure radpiramid;
...
kv(x - 40, 50, clGreen);
y := 100; <--------------------
for var i := 1 to 3 do
kv(x - 20 * i, y, clOrange);
y := 150; <-----------------------
for var i := 1 to 5 do
kv(x + 40 - 20 * (i + 1), y, clRed);
...
You must increase this value of y to get pyramids to appear at different heights of the window.

The '+' operation is not applicable to the types function(x: real): real and real. Check the operation of the program for a = 0.1; b = 1.0; h = 0.1;

Check the operation of the program for a = 0.1; b = 1.0; h = 0.1; select the value of parameter n depending on the task.
Why am I getting an error? What is the best way to solve this problem? How to simplify?
var i, n: integer;
x, k, h, sx: real;
function Y(x: real): real;
begin
Y := x * arctan(x) - 0.5 * ln(1.0 + x * x)
end;
function S(x: real): real;
var sum, xx, p, znak, e: real;
begin
S := 0.5 * x * x;
p := x * x;
xx := - x * x;
k := 2;
e := 1e303;
while abs(e) > 1e-14 do
begin
k := k + 2;
p := p * xx;
e := p / (k * (k - 1));
S := S + e
end
end;
begin
h := 0.1;
writeln('x': 2, 'S(x)': 14,
'Y(x)': 18, 'n': 15);
for i := 1 to 10 do
begin
x := i * h;
sx := S(x);
n := round(k / 2);
writeln(x: 3: 1, sx: 18: 14,
Y(x): 18: 14, n: 10)
end
end.
-->The '+' operation is not applicable to the types function(x: real): real and real
I tried to solve the problem based on the fact that x is the range a to b with a step h:
program test;
var y, a, b, h, x, Sx, Yx, n:real;
begin
a:=0.1;
b:=1.0;
h:=0.1;
x:=a;
n:=0;
while x<=b do
begin
Yx:= x*arctan(x)-ln(sqrt(1+exp(x)));
x:=x+h;
writeln(Yx);
writeln('---------------------', n); n:=n+1;
end;
end.
But I do not know how to get S(x)
The error message means that the first argument of + is a function. I'll bet this is the S := S + e line. While you can assign to S to set the return value of S, you can't read it back like that.
You can refer to a function inside that function; this is used with recursion. But then you'll need to actually call yourself. E.g. Fibonacci := Fibonacci(i-1) * i. Now the left side of * is not a function, but the result of a function call.
Solution: just use a temporary variable, and assign that to S at the very end; of S

restrict object so it can't go off the window

program CircleMoving;
uses SwinGame, sgTypes;
procedure Main();
var
x, y, CIRCLE_RADIUS: Single; screenColour: Color;
begin
OpenGraphicsWindow('Character Moving', 800, 600);
Delay(5000);
x := 400;
y := 300;
CIRCLE_RADIUS := 150;
screenColour := ColorWhite;
repeat
clearScreen(screenColour);
fillCircle(ColorGreen, x, y, CIRCLE_RADIUS);
RefreshScreen(60);
Processevents();
if KeyDown(LeftKey) and (x - CIRCLE_RADIUS < ScreenWidth()) then
begin
x := x - 1;
end;
if KeyDown(RightKey) and (x + CIRCLE_RADIUS < ScreenWidth()) then
begin
x := x + 1;
end;
if KeyDown(UpKey) and (y - CIRCLE_RADIUS < ScreenHeight()) then
begin
y := y - 1;
end;
if KeyDown(DownKey) and (y + CIRCLE_RADIUS < ScreenHeight()) then
begin
y := y + 1;
end;
until WindowCloseRequested();
end;
begin
Main();
end.
At the moment when I run the code it works other then when I move the circle to the left and up it goes off the window, I do not want this to happen. I want it to be restricted so the circle will stop and wont go any further once it hits the edge. I want it to be the same on all side so when I move the circle in any direction it will stop at the edge of the window. Moving the circle to the right and down works but left and up does not. I believe the problem is at the if statements starting at line 22. How do I change my code to fix this?

Lua, table converted to a number?

I am simply adding numbers together but it continues to error. I used type() to check if vector is a table or not and it always said it was but it continues to say that it is a number.
Can anyone tell me why this is happening and a way to fix it(the variable vector is a vector3 object)? Any help is greatly appreciated.
Vector3:
function new(x, y, z)
return setmetatable({x = x, y = y, z = z}, meta) --{} has public variables
end
All of the Vector3 file here: http://pastebin.com/csBmJG36
ERROR:
attempt to index local 'vector' (a number value)
SCRIPT:
function translate(object, x, y, z)
for i, v in pairs(object) do
if (i == "Vertices") then
for _, q in pairs(v) do
for l, vector in pairs(q) do
vector.x = vector.x + x;
vector.y = vector.y + y;
vector.z = vector.z + z;
end
end
end
end
end
Let's refactor your code by removing the loop-switch anti-pattern:
function translate(object, x, y, z)
for _, q in pairs(object.Vertices) do
for l, vector in pairs(q) do
-- Test the type of vector here...
vector.x = vector.x + x;
vector.y = vector.y + y;
vector.z = vector.z + z;
end
end
end
So, the error occurs with an access to object.Vertices[_][l].x.
That would be a curious vertex-list which contains lists of vertex-lists instead.

Speed up procedure to resize a grid column

I have a procedure to auto-resize a column in a grid to accommodate for the largest string in that column. However when there's over 2,000 records in the grid, it takes a little too much time. Any tips on speeding this up?
//lstSKU = grid
procedure TfrmExcel.ResizeCol(const ACol: Integer);
var
M: Integer;
X: Integer;
S: String;
R: TRect;
begin
M:= 20;
lstSKU.Canvas.Font.Assign(lstSKU.Font);
for X:= 1 to lstSKU.RowCount - 1 do begin
S:= lstSKU.Cells[ACol, X];
R:= Rect(0, 0, 20, 20);
DrawText(lstSKU.Canvas.Handle, PChar(S), Length(S), R,
DT_LEFT or DT_VCENTER or DT_CALCRECT);
if R.Right > M then
M:= R.Right;
end;
M:= M + 15;
lstSKU.ColWidths[ACol]:= M;
end;
Is this a standard TStringGrid/TDrawGrid?
You can iterate through using Canvas.TextWidth(S) instead to measure the content width of each cell, save the largest, add any padding, and then set the Grid.ColWidths[Col] := M;. This will trigger a single redraw if needed. (Basically what you're doing, without repeating the drawing operation 2001 times.)
procedure TfrmExcel.ResizeCol(const ACol: Integer);
var
M, T: Integer;
X: Integer;
S: String;
begin
M := 20;
for X := 1 to lstSKU.RowCount - 1 do
begin
S:= lstSKU.Cells[ACol, X];
T := lstSKU.Canvas.TextWidth(S);
if T > M then
M := T;
end;
M := M + 15;
lstSKU.ColWidths[ACol] := M;
end;
If you want to set both width and height of the cell to accomodate larger fonts or something, use TextExtent instead of TextWidth; TextExtent returns a TSize, from which you can read Width and Height.
Although already answered, I'm posting the final code, which you can use with any string grid (TStringGrid). It resized 3,000 records with 27 columns in 2.3 seconds, as opposed to the prior 6.4 average.
//AGrid = Grid containing column to be resized
//ACol = Column index of grid to be resized
//AMin = Minimum column width
procedure ResizeCol(AGrid: TStringGrid; const ACol, AMin: Integer);
var
M, T: Integer; //M=Maximum Width; T=Current Text
X: Integer; //X=Loop Counter
begin
M:= AMin; //Begin with minimum width
AGrid.Canvas.Font.Assign(AGrid.Font);
for X:= 1 to AGrid.RowCount - 1 do begin
T:= AGrid.Canvas.TextWidth(AGrid.Cells[ACol, X]);
if T > M then M:= T;
end;
AGrid.ColWidths[ACol]:= M + AMin;
end;

Resources