mixster
2009-07-04 18:59:10
Generates a TPA of an oval at location specified, like TPAFromBox.
mx and my are the center of the oval, with maxx being the max width and maxy being max height of the oval from the center point, so maxx would actually give an oval with double the number specified.
One use is a M/Mouse that performs what it would normally do in an ovular area specified.
Of course, it can also be used for drawing etc.
I do also have a very good reason for using Pythagoras over Trigonometry for this.
Edit: It is very inefficient to use TPAFromOval in a M/Mouse thingy like that as it could be made much faster by only generating one point, but it's a nice example of what you could do with it. Something like
mx and my are the center of the oval, with maxx being the max width and maxy being max height of the oval from the center point, so maxx would actually give an oval with double the number specified.
function TPAFromOval(mx, my, maxx, maxy: Integer): TPointArray;
var
x, y, i, ii, d, h: Integer;
r: Extended;
begin
r := maxx / maxy; // ratio that sets "fatness" of oval
h := -1; // Handles high of the result array
SetLength(Result, maxx * maxy * 4); // Ensure result array is long enough to hold all points
for i := -maxy to maxy do // loop through y axis
begin
y := my + i; // Set the y position
d := Round(Sqrt(Sqr(maxy) - Sqr(i)) * r); // Get the distance from centre to outside of oval using b^2 = c^2 - a^2 then multiplying by ratio to alter thickness
x := mx - d; // Get the left most x position
d := d + d; // Double radius to turn it into the diameter
h := h + 1; // Increase the height
for ii := 0 to d do // Loop through the current row
Result[h + ii] := Point(x + ii, y); // Add the point in the row
h := h + d; // Increment the high by the amount added
end;
SetLength(Result, h + d + 1); // Set the length so it only stores set points
end;
One use is a M/Mouse that performs what it would normally do in an ovular area specified.
procedure MouseOval(x, y, rx, ry, click: Integer);
var
tp: TPointArray;
i: Integer;
begin
tp := TPAFromOval(x, y, rx, ry);
i := Random(Length(tp));
case click of
1,2: Mouse(tp[i].x, tp[i].y, 0, 0, click = 1);
3: MMouse(tp[i].x, tp[i].y, 0, 0);
else
srl_Warn('MouseOval', 'ClickType is NOT a valid number!', warn_AllVersions);
end;
end;
(I stole the click bit from MouseBox, but it doesn't act like MouseBox since it is passed a point and a random x and y like M/Mouse rather than the two sets of points MouseBox uses)Of course, it can also be used for drawing etc.
I do also have a very good reason for using Pythagoras over Trigonometry for this.
Edit: It is very inefficient to use TPAFromOval in a M/Mouse thingy like that as it could be made much faster by only generating one point, but it's a nice example of what you could do with it. Something like
function TPFromOval(cx, cy, mx, my: Integer): TPoint;
var
m: Integer;
r: Extended;
begin
r := mx / my; // Get the ratio of mx per my
m := Random(my - 1); // Get random y axis offset
if (Random(2) = 0) then // If 50/50 chance is true
m := -m - 1; // Set to minus with an additional -1
Result.y := cy + m; // Add the offset to the centre point
m := Random(Round(Sqrt(Sqr(my) - Sqr(m)) * r) - 1); // Get random x offset
if (Random(2) = 0) then // If 50/50 chance is true
m := -m - 1; // Set to minus with an additional -1
Result.x := cx + m; // Add the offset to the centre point
end;
Would be better suited to being using in a time critical function/procedure :)
