Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [SIZE="0"][url=http://villavu.com/forum/showthread.php?t=82205]String Handling Commands[/url] |[/SIZE] [SIZE="5"][COLOR="red"]Point Commands[/COLOR][/SIZE] [SIZE="0"]| [url=http://villavu.com/forum/showthread.php?t=104649]Box Commands[/url] | [url=http://villavu.com/forum/showthread.php?t=104689]Integer Commands[/url][/SIZE]
- Time for some point-related commands! :p
- Added small examples for all commands, just to show how they work (due to missing those code comments), although most of the functions/procedures are pretty much self-explanatory...
- Also most (if not all) will have small explanations included aswell.
- [b]List of [color=blue]Functions[/color] & [color=blue]Procedures[/color]:[/b]
- [code][u]### / Date Added / Command Name[/u]
- 000 / 07-14-2013 / PtSetConstraints()
- 001 / 07-14-2013 / Angle()
- 002 / 07-14-2013 / Distance2()
- 003 / 07-14-2013 / OffsetPointEx()
- 004 / 07-14-2013 / GetOffsetFromPoints()
- 005 / 07-14-2013 / GetPointWithOffset()
- 006 / 07-14-2013 / PointSteps()
- 007 / 07-14-2013 / GetPointByStep()
- 008 / 07-14-2013 / GetTPALine()
- 009 / 07-18-2013 / InEllipse()
- 010 / 07-18-2013 / InCircle()
- 011 / 07-14-2013 / TPAClone()
- 012 / 07-14-2013 / TPACopy()
- 013 / 07-14-2013 / TPACopyEx()
- 014 / 07-14-2013 / TPAAppend()
- 015 / 07-14-2013 / TPAAdd()
- 016 / 07-14-2013 / TPAInsert()
- 017 / 07-14-2013 / TPAPlant()
- 018 / 07-14-2013 / TPADelete()
- 019 / 07-14-2013 / TPARemove()
- 020 / 07-14-2013 / TPAGet()
- 021 / 07-14-2013 / TPAPickEx()
- 022 / 07-14-2013 / TPAMove()
- 023 / 07-14-2013 / TPAReplace()
- 024 / 07-14-2013 / TPAReplaceEx()
- 025 / 07-14-2013 / TPACreate()
- 026 / 07-14-2013 / TPACreateEx()
- 027 / 07-14-2013 / TPABuild()
- 028 / 07-18-2013 / TPAFromEllipseEx()
- 029 / 07-18-2013 / TPAFromCircleEx()
- 030 / 07-14-2013 / TPAFill()
- 031 / 07-14-2013 / TPAFillEx()
- 032 / 07-14-2013 / TPAFillIDs()
- 033 / 07-14-2013 / TPAFillIDsEx()
- 034 / 07-14-2013 / TPAXValues()
- 035 / 07-14-2013 / TPAYValues()
- 036 / 07-19-2013 / TPASwapValues()
- 037 / 07-14-2013 / TPADensity()
- 038 / 07-17-2013 / TPACenter()
- 039 / 07-14-2013 / TPAExtractEveryX()
- 040 / 07-14-2013 / TPAExtractEveryXEx()
- 041 / 07-14-2013 / TPAFilterEveryX()
- 042 / 07-14-2013 / TPAFilterEveryXEx()
- 043 / 07-15-2013 / TPAExtractBoxes()
- 044 / 07-15-2013 / TPAFilterBoxes()
- 045 / 07-15-2013 / TPAExtractPoints()
- 046 / 07-15-2013 / TPAFilterPoints()
- 047 / 07-17-2013 / TPAExtractNearbyPoints()
- 048 / 07-17-2013 / TPAExtractNearbyPointsEx()
- 049 / 07-17-2013 / TPAFilterNearbyPoints()
- 050 / 07-17-2013 / TPAFilterNearbyPointsEx()
- 051 / 07-14-2013 / TPASetConstraints()
- 052 / 07-19-2013 / TPAUnusedBoxPixels()
- 053 / 07-19-2013 / TPAUsedBoxPixells()
- 054 / 07-14-2013 / TPAReverse()
- 055 / 07-15-2013 / TPAInvert()
- 056 / 07-19-2013 / TPAEdge()
- 057 / 07-17-2013 / TPARotate()
- 058 / 07-19-2013 / TPAOffset()
- 059 / 07-19-2013 / TPAOffsetEx()
- 060 / 07-14-2013 / TPAUnique()
- 061 / 07-20-2013 / TPAUnique2()
- 062 / 07-14-2013 / TPAUniqueIDs()
- 063 / 07-14-2013 / TPAGrid()
- 064 / 07-14-2013 / TPARow()
- 065 / 07-14-2013 / TPAColumn()
- 066 / 07-14-2013 / TPACombine()
- 067 / 07-14-2013 / TPAContains()
- 068 / 07-17-2013 / TPAContainsEx()
- 069 / 07-17-2013 / TPAContainsTPA()
- 070 / 07-14-2013 / TPAPos()
- 071 / 07-14-2013 / TPAEmpty()
- 072 / 07-15-2013 / TPABounds()
- 073 / 07-15-2013 / TPAMean()
- 074 / 07-17-2013 / TPASplitEx()
- 075 / 07-17-2013 / TPAGroupEx()
- 076 / 07-14-2013 / TPAToParts() [*]
- 077 / 07-14-2013 / ATPAMerge()
- 078 / 07-15-2013 / ATPAEmpty()
- 079 / 07-15-2013 / ATPASize()
- 080 / 07-15-2013 / ATPAClean()
- 081 / 07-17-2013 / ATPABounds()
- 082 / 07-17-2013 / ATPAAllBounds()
- [i]* = Amount of custom types required.[/i][/code]
- [spoiler="PtSetConstraints"]
- [simba]{==============================================================================]
- Explanation: Sets point (pt) inside area, if its not inside it.
- Returns true if constraints were set to pt.
- [==============================================================================}
- function PtSetConstraints(var pt: TPoint; area: TBox): Boolean;
- var
- tmp: TPoint;
- begin
- if ((area.X1 <= area.X2) and (area.Y1 <= area.Y2)) then
- begin
- tmp := TPoint(pt);
- if (pt.X < area.X1) then
- pt.X := Integer(area.X1)
- else
- if (pt.X > area.X2) then
- pt.X := Integer(area.X2);
- if (pt.Y < area.Y1) then
- pt.Y := Integer(area.Y1)
- else
- if (pt.Y > area.Y2) then
- pt.Y := Integer(area.Y2);
- Result := ((pt.X <> tmp.X) or (pt.Y <> tmp.Y));
- end else
- Result := False;
- end;
- var
- pt: TPoint;
- begin
- pt := Point(99, 100);
- if PtSetConstraints(pt, IntToBox(10, 10, 99, 99)) then
- WriteLn(ToStr(pt));
- end.[/simba]
- [/spoiler]
- [spoiler="Angle"]
- [simba]{==============================================================================]
- Explanation: Calculates the angle of pt1 and pt2 coordinates.
- NOTE: Result is based on COMPASS degrees: http://www.blackknightassociation.com/Images/acirclueis360degrees.jpg
- [==============================================================================}
- function Angle(pt1, pt2: TPoint): Extended;
- begin
- Result := ((ArcTan2((pt2.Y - pt1.Y), (pt2.X - pt1.X)) * (180.0 / Pi)) + 90.0);
- if (Result < 0.0) then
- Result := (Result + 360.0);
- end;
- begin
- WriteLn(Angle(Point(15, 10), Point(24, 4)));
- end.[/simba]
- [/spoiler]
- [spoiler="Distance2"]
- [simba]{==============================================================================]
- Explanation: Returns the exact distance from pt1 to pt2.
- [==============================================================================}
- function Distance2(pt1, pt2: TPoint): Extended;
- begin
- if ((pt1.X <> pt2.X) or (pt1.Y <> pt2.Y)) then
- Result := Sqrt(Sqr(pt1.X - pt2.X) + Sqr(pt1.Y - pt2.Y))
- else
- Result := 0.0;
- end;
- begin
- WriteLn(Distance2(Point(15, 10), Point(24, 4)));
- end.[/simba]
- [/spoiler]
- [spoiler="OffsetPointEx"]
- [simba]{==============================================================================]
- Explanation: Offsets pt with radius & angle (degrees).
- NOTE: Angle is based on COMPASS degrees: http://www.blackknightassociation.com/Images/acirclueis360degrees.jpg
- [==============================================================================}
- procedure OffsetPointEx(var pt: TPoint; radius, angle: Extended);
- begin
- pt := Point(Round(radius * Sin(angle * (Pi / 180)) + pt.X), Round(-radius * Cos(angle * (Pi / 180)) + pt.Y));
- end;
- var
- pt: TPoint;
- begin
- pt := Point(15, 10);
- OffsetPointEx(pt, 10.8166538263919, 56.3099324740202);
- WriteLn(pt);
- end.[/simba]
- [/spoiler]
- [spoiler="GetOffsetFromPoints"]
- [simba]{==============================================================================]
- Explanation: Stores the offset from pt1 to pt2 to radius and angle (degrees).
- NOTE: Angle is based on COMPASS degrees: http://www.blackknightassociation.com/Images/acirclueis360degrees.jpg
- [==============================================================================}
- procedure GetOffsetFromPoints(pt1, pt2: TPoint; var radius, angle: Extended);
- var
- X, Y: Integer;
- begin
- X := (pt2.X - pt1.X);
- Y := (pt2.Y - pt1.Y);
- radius := Sqrt(Pow(X, 2) + Pow(Y, 2));
- angle := ((ArcTan2(Y, X) * (180 / Pi)) + 90.0);
- if (angle < 0.0) then
- angle := (angle + 360.0);
- end;
- var
- r, a: Extended;
- begin
- GetOffsetFromPoints(Point(15, 10), Point(24, 4), r, a);
- WriteLn('Radius: ' + FloatToStr(r) + ', Angle: ' + FloatToStr(a));
- end.[/simba]
- [/spoiler]
- [spoiler="GetPointWithOffset"]
- [simba]{==============================================================================]
- Explanation: Returns the point with radius and angle offset from startPt.
- NOTE: Angle is based on COMPASS degrees: http://www.blackknightassociation.com/Images/acirclueis360degrees.jpg
- [==============================================================================}
- function GetPointWithOffset(startPt: TPoint; radius, angle: Extended): TPoint;
- begin
- Result := Point(Round(radius * Sin(angle * (Pi / 180)) + startPt.X), Round(-radius * Cos(angle * (Pi / 180)) + startPt.Y));
- end;
- begin
- WriteLn(GetPointWithOffset(Point(15, 10), 10.8166538263919, 56.3099324740202));
- end.[/simba]
- [/spoiler]
- [spoiler="PointSteps"]
- [simba]{==============================================================================]
- Explanation: Returns the amount of point steps there is fromPt => toPt.
- [==============================================================================}
- function PointSteps(fromPt, toPt: TPoint): Integer;
- begin
- if ((fromPt.X <> toPt.X) or (fromPt.Y <> toPt.Y)) then
- Result := Max((Max(fromPt.X, toPt.X) - Min(fromPt.X, toPt.X)), (Max(fromPt.Y, toPt.Y) - Min(fromPt.Y, toPt.Y)))
- else
- Result := 0;
- end;
- var
- a, b: TPoint;
- begin
- a := Point(15, 10);
- b := Point(24, 4);
- WriteLn('Count of steps from ' + ToStr(a) + ' to ' + ToStr(b) + ': ' + ToStr(PointSteps(a, b)));
- end.[/simba]
- [/spoiler]
- [spoiler="GetPointByStep"]
- [simba]{==============================================================================]
- Explanation: Returns the point with step fromPt => toPt.
- [==============================================================================}
- function GetPointByStep(fromPt, toPt: TPoint; step: Integer): TPoint;
- var
- e: Extended;
- p: TPoint;
- begin
- if not (((fromPt.X = toPt.X) and (fromPt.Y = toPt.Y)) or (step < 0) or (step > Max((Max(fromPt.X, toPt.X) - Min(fromPt.X, toPt.X)), (Max(fromPt.Y, toPt.Y) - Min(fromPt.Y, toPt.Y))))) then
- begin
- e := (step / MaxE(Round(Abs(fromPt.X - toPt.X)), Round(Abs(fromPt.Y - toPt.Y))));
- Result.X := (fromPt.X + Round((toPt.X - fromPt.X) * e));
- Result.Y := (fromPt.Y + Round((toPt.Y - fromPt.Y) * e));
- end else
- Result := p;
- end;
- var
- pt1, pt2: TPoint;
- step: Integer;
- begin
- ClearDebug;
- pt1 := Point(15, 10);
- pt2 := Point(24, 4);
- for step := 0 to 9 do
- WriteLn(GetPointByStep(pt1, pt2, step));
- end.[/simba]
- [/spoiler]
- [spoiler="GetTPALine"]
- [simba]{==============================================================================]
- Explanation: Returns the line of points fromPt => toPt.
- [==============================================================================}
- function GetTPALine(fromPt, toPt: TPoint): TPointArray;
- var
- i, h: integer;
- begin
- if ((fromPt.X <> toPt.X) or (fromPt.Y <> toPt.Y)) then
- begin
- h := Max(Round(Abs(fromPt.X - toPt.X)), Round(Abs(fromPt.Y - toPt.Y)));
- SetLength(Result, (h + 1));
- for i := 0 to h do
- Result[i] := Point((fromPt.X + Round((toPt.X - fromPt.X) * (Extended(i) / h))), (fromPt.Y + Round((toPt.Y - fromPt.Y) * (Extended(i) / h))));
- end else
- Result := [fromPt];
- end;
- var
- pt1, pt2: TPoint;
- TPA: TPointArray;
- h, i: Integer;
- begin
- ClearDebug;
- pt1 := Point(15, 10);
- pt2 := Point(24, 4);
- WriteLn('GetTPALine:');
- TPA := GetTPALine(pt1, pt2);
- h := High(TPA);
- for i := 0 to h do
- WriteLn('TPA[' + IntToStr(i) + ']: ' + IntToStr(TPA[i].X) + ', ' + IntToStr(TPA[i].Y));
- SetLength(TPA, 0);
- end.[/simba]
- [/spoiler]
- [spoiler="InEllipse"]
- [simba]{==============================================================================]
- Explanation: Returns true if pt is inside the given ellipse,
- defined by the center point and radius.
- [==============================================================================}
- function InEllipse(pt, center: TPoint; XRadius, YRadius: Extended): Boolean;
- begin
- Result := (Sqr((pt.X - center.X) / XRadius) + Sqr((pt.Y - center.Y) / YRadius) <= 1);
- end;
- var
- x: Integer;
- begin
- ClearDebug;
- for x := 20 to 26 do
- if InEllipse(Point(x, 20), Point(30, 20), 7, 12) then
- WriteLn('Point(' + IntToStr(x) + ', 20) is inside ellipse!')
- else
- WriteLn('Point(' + IntToStr(x) + ', 20) is not inside ellipse...')
- end.[/simba]
- [/spoiler]
- [spoiler="InCircle"]
- [simba]{==============================================================================]
- Explanation: Returns true if pt is inside the given circle,
- defined by the center point and radius.
- [==============================================================================}
- function InCircle(pt, center: TPoint; radius: Extended): Boolean;
- begin
- Result := (Sqr((pt.X - center.X) / radius) + Sqr((pt.Y - center.Y) / radius) <= 1);
- end;
- var
- x: Integer;
- begin
- ClearDebug;
- for x := 20 to 26 do
- if InCircle(Point(x, 20), Point(30, 20), 7) then
- WriteLn('Point(' + IntToStr(x) + ', 20) is inside circle!')
- else
- WriteLn('Point(' + IntToStr(x) + ', 20) is not inside circle...')
- end.[/simba]
- [/spoiler]
- [spoiler="TPAClone"]
- [simba]{==============================================================================]
- Explanation: Returns copy ("clone") of TPA safely
- [==============================================================================}
- function TPAClone(TPA: TPointArray): TPointArray;
- var
- i, l: Integer;
- begin
- l := Length(TPA);
- SetLength(Result, l);
- for i := 0 to (l - 1) do
- Result[i] := TPoint(TPA[i]);
- end;
- var
- TPA: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- WriteLn(TPAClone(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPACopy"]
- [simba]{==============================================================================]
- Explanation: Version of Copy() function for TPointArrays.
- [==============================================================================}
- function TPACopy(TPA: TPointArray; startIndex, count: Integer): TPointArray;
- var
- i, l, t: Integer;
- begin
- l := Length(TPA);
- if (startIndex < 0) then
- startIndex := 0;
- if ((l >= startIndex) and (count > 0)) then
- begin
- t := (l - startIndex);
- if (count > t) then
- count := t;
- SetLength(Result, count);
- for i := startIndex to ((startIndex + count) - 1) do
- Result[(i - startIndex)] := TPoint(TPA[i]);
- end else
- SetLength(Result, 0);
- end;
- var
- TPA: TPointArray;
- begin
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- WriteLn(ToStr(TPACopy(TPA, 1, 3)));
- end.[/simba]
- [/spoiler]
- [spoiler="TPACopyEx"]
- [simba]{==============================================================================]
- Explanation: Copies TPA from pos1 to pos2. Reverse copies with pos1>pos2 (flexible!).
- [==============================================================================}
- function TPACopyEx(TPA: TPointArray; pos1, pos2: Integer): TPointArray;
- var
- i, l: Integer;
- begin
- l := Length(TPA);
- if (l > 0) then
- begin
- if (pos1 < 0) then
- pos1 := 0;
- if (pos1 > (l - 1)) then
- pos1 := (l - 1);
- if (pos2 < 0) then
- pos2 := 0;
- if (pos2 > (l - 1)) then
- pos2 := (l - 1);
- if (pos1 <> pos2) then
- begin
- {$IFNDEF Lape}
- SetLength(Result, (iAbs(pos1 - pos2) + 1));
- {$ELSE}
- SetLength(Result, Integer(Abs(pos1 - pos2) + 1));
- {$ENDIF}
- if (pos1 < pos2) then
- begin
- for i := pos1 to pos2 do
- Result[(i - pos1)] := TPoint(TPA[i]);
- end else
- for i := pos1 downto pos2 do
- Result[(pos1 - i)] := TPoint(TPA[i]);
- end else
- Result := [TPoint(TPA[pos1])];
- end else
- SetLength(Result, 0);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- WriteLn(ToStr(TPACopyEx(TPA, 1, 3)));
- WriteLn(ToStr(TPACopyEx(TPA, 3, 1)));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAAppend"]
- [simba]{==============================================================================]
- Explanation: Appends TPA with x.
- [==============================================================================}
- procedure TPAAppend(var TPA: TPointArray; x: TPoint);
- var
- aL: Integer;
- begin
- aL := (Length(TPA) + 1);
- SetLength(TPA, aL);
- TPA[(aL - 1)] := TPoint(x);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7)];
- TPAAppend(TPA, Point(8, 9));
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAAdd"]
- [simba]{==============================================================================]
- Explanation: Adds all addTPA items to TPA. Returns the highest index in the end.
- [==============================================================================}
- function TPAAdd(var TPA: TPointArray; addTPA: TPointArray): Integer;
- var
- h, l, i: Integer;
- begin
- h := High(addTPA);
- if (h > -1) then
- begin
- l := Length(TPA);
- SetLength(TPA, (l + (h + 1)));
- for i := 0 to h do
- TPA[(i + l)] := TPoint(addTPA[i]);
- end;
- Result := High(TPA);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3)];
- TPAAdd(TPA, [Point(4, 5), Point(6, 7), Point(8, 9)]);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAInsert"]
- [simba]{==============================================================================]
- Explanation: Inserts pt to index position in TPA.
- [==============================================================================}
- procedure TPAInsert(var TPA: TPointArray; index: Integer; pt: TPoint);
- var
- i, l: Integer;
- begin
- l := Length(TPA);
- SetLength(TPA, (l + 1));
- if (index < 0) then
- index := 0;
- if (index > l) then
- index := l;
- if (l > index) then
- for i := (l - 1) downto index do
- TPA[(i + 1)] := TPoint(TPA[i]);
- TPA[index] := TPoint(pt);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(6, 7), Point(8, 9)];
- TPAInsert(TPA, 2, Point(4, 5));
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAPlant"]
- [simba]{==============================================================================]
- Explanation: Plants/places pts to index position in TPA.
- Like TPAInsert(), with an exception that this inserts array of points.
- Returns the highest index from TPA in the end.
- [==============================================================================}
- function TPAPlant(var TPA: TPointArray; index: Integer; pts: TPointArray): Integer;
- var
- i, l, h: Integer;
- begin
- h := High(pts);
- if (h > -1) then
- begin
- l := Length(TPA);
- SetLength(TPA, (l + (h + 1)));
- if (index < 0) then
- index := 0;
- if (index > l) then
- index := l;
- for i := (l + (h + 1) - 1) downto (index + (h + 1)) do
- TPA[i] := TPA[(i - (h + 1))];
- for i := 0 to h do
- TPA[(i + index)] := TPoint(pts[i]);
- end;
- Result := High(TPA);
- end;
- var
- TPA: TPointArray;
- begin
- TPA := [Point(0, 1), Point(8, 9)];
- TPAPlant(TPA, 1, [Point(2, 3), Point(4, 5), Point(6, 7)]);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPADelete"]
- [simba]{==============================================================================]
- Explanation: Deletes a point from TPA, x = index. Returns true with success.
- [==============================================================================}
- function TPADelete(var TPA: TPointArray; x: Integer): Boolean;
- var
- i, h: Integer;
- begin
- h := High(TPA);
- Result := ((x <= h) and (x > -1));
- if not Result then
- Exit;
- for i := x to (h - 1) do
- TPA[i] := TPA[(i + 1)];
- SetLength(TPA, h);
- end;
- var
- TPA: TPointArray;
- begin
- TPA := [Point(0, 1), Point(2, 3), Point(1000, 1000), Point(4, 5), Point(6, 7), Point(8, 9)];
- if TPADelete(TPA, 2) then
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPARemove"]
- [simba]{==============================================================================]
- Explanation: Removes points from TPA, x = array of indexes.
- NOTE: RECURSIVE/DYNAMIC! Pay attention to IDs.. In most cases you'll need to use reversed order.
- Also, being dynamic means that this doesn't pay attention to duplicate indexes in x,
- so this will delete any of those duplicate IDs then multiple times, when it is possible!
- [==============================================================================}
- procedure TPARemove(var TPA: TPointArray; x: TIntegerArray);
- var
- i, i2, h, h2: Integer;
- begin
- h := High(TPA);
- h2 := High(x);
- if ((h < 0) or (h2 < 0)) then
- Exit;
- for i2 := 0 to h2 do
- if ((x[i2] <= h) and (x[i2] > -1)) then
- begin
- for i := x[i2] to (h - 1) do
- TPA[i] := TPA[(i + 1)];
- Dec(h);
- end;
- SetLength(TPA, (h + 1));
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(6, 9), Point(0, 1), Point(6, 9), Point(2, 3), Point(4, 5), Point(6, 9), Point(6, 9), Point(6, 7), Point(6, 9), Point(8, 9)];
- TPARemove(TPA, [0, 2, 5, 6, 8]);
- WriteLn(ToStr(TPA) + ' [Without reversed order]');
- SetLength(TPA, 0);
- TPA := [Point(6, 9), Point(0, 1), Point(6, 9), Point(2, 3), Point(4, 5), Point(6, 9), Point(6, 9), Point(6, 7), Point(6, 9), Point(8, 9)];
- TPARemove(TPA, [8, 6, 5, 2, 0]);
- WriteLn(ToStr(TPA) + ' [With reversed order]');
- SetLength(TPA, 0);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAGet"]
- [simba]{==============================================================================]
- Explanation: Returns array of items from TPA by IDs. Ignores invalid ID's.
- [==============================================================================}
- function TPAGet(TPA: TPointArray; IDs: TIntegerArray): TPointArray;
- var
- i, h, h2, r: Integer;
- begin
- h := High(TPA);
- h2 := High(IDs);
- if ((h2 > -1) and (h > -1)) then
- begin
- SetLength(Result, (h2 + 1));
- for i := 0 to h2 do
- if ((IDs[i] <= h) and (IDs[i] > -1)) then
- begin
- Result[r] := TPoint(TPA[IDs[i]]);
- Inc(r);
- end;
- end;
- SetLength(Result, r);
- end;
- var
- TPA: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- WriteLn(TPAGet(TPA, [-999, 0, 2, 4, 3, 1, 0, -999]));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAPickEx"]
- [simba]{==============================================================================]
- Explanation: Returns points (by pick_IDs) from TPA and then deletes em.
- NOTE: Ignores invalid indexes. DYNAMIC (so place indexes in reversed order to get em correctly)!
- [==============================================================================}
- function TPAPickEx(var TPA: TPointArray; pick_IDs: TIntegerArray): TPointArray;
- var
- h, h2, t, i, r: Integer;
- begin
- h2 := High(TPA);
- h := High(pick_IDs);
- if ((h2 > -1) and (h > -1)) then
- begin
- SetLength(Result, (h2 + 1));
- for i := 0 to h do
- if ((pick_IDs[i] <= h2) and (pick_IDs[i] > -1)) then
- begin
- Result[r] := TPoint(TPA[pick_IDs[i]]);
- Inc(r);
- for t := pick_IDs[i] to (h2 - 1) do
- TPA[t] := TPA[(t + 1)];
- SetLength(TPA, h2);
- Dec(h2);
- if (h2 < 0) then
- Break;
- end;
- SetLength(Result, r);
- end else
- SetLength(Result, 0);
- end;
- var
- TPA, TPA2: TPointArray;
- begin
- ClearDebug;
- TPAFromBoxWrap(IntToBox(0, 0, 2, 2), TPA);
- WriteLn('TPA (Before picking): ' + ToStr(TPA));
- TPA2 := TPAPickEx(TPA, [8, 6, 4, 2, 0]);
- WriteLn('TPA (After picking): ' + ToStr(TPA));
- WriteLn('TPA2 (Picked points): ' + ToStr(TPA2));
- SetLength(TPA, 0);
- SetLength(TPA2, 0);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAMove"]
- [simba]{==============================================================================]
- Explanation: Moves oldIndex to newIndex in TPA. Returns true, if movement was succesfully done!
- [==============================================================================}
- function TPAMove(var TPA: TPointArray; oldIndex, newIndex: Integer): Boolean;
- var
- h, i: Integer;
- begin
- h := High(TPA);
- Result := ((h > 0) and (oldIndex <> newIndex) and InRange(oldIndex, 0, h) and InRange(newIndex, 0, h));
- if Result then
- if (oldIndex > newIndex) then
- begin
- for i := oldIndex downto (newIndex + 1) do
- Swap(TPA[i], TPA[(i - 1)]);
- end else
- for i := oldIndex to (newIndex - 1) do
- Swap(TPA[i], TPA[(i + 1)]);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(6, 7), Point(2, 3), Point(4, 5), Point(8, 9)];
- TPAMove(TPA, 1, 3);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAReplace"]
- [simba]{==============================================================================]
- Explanation: Replaces all oldPoint's in TPA with newPoint.
- [==============================================================================}
- procedure TPAReplace(var TPA: TPointArray; oldPoint, newPoint: TPoint);
- var
- h, i: Integer;
- begin
- if ((oldPoint.X <> newPoint.X) and (oldPoint.Y <> newPoint.Y)) then
- begin
- h := High(TPA);
- for i := 0 to h do
- if ((TPA[i].X = oldPoint.X) and (TPA[i].Y = oldPoint.Y)) then
- TPA[i] := TPoint(newPoint);
- end;
- end;
- var
- TPA: TPointArray;
- begin
- SetLength(TPA, 10);
- TPA[0] := Point(0, 1);
- TPA[1] := Point(1, 0);
- TPA[2] := Point(1, 1);
- TPAReplace(TPA, Point(0, 0), Point(9, 9));
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAReplaceEx"]
- [simba]{==============================================================================]
- Explanation: Replaces all oldPoints' in TPA with newPoint.
- [==============================================================================}
- procedure TPAReplaceEx(var TPA: TPointArray; oldPoints: TPointArray; newPoint: TPoint);
- var
- a, b, x, y: Integer;
- begin
- y := High(oldPoints);
- if (y > -1) then
- begin
- b := High(TPA);
- for a := 0 to b do
- for x := 0 to y do
- if ((TPA[a].X = oldPoints[x].X) and (TPA[a].Y = oldPoints[x].Y)) then
- begin
- TPA[a] := TPoint(newPoint);
- Break;
- end;
- end;
- end;
- var
- TPA: TPointArray;
- begin
- SetLength(TPA, 10);
- TPA[0] := Point(1, 1);
- TPA[2] := Point(1, 1);
- TPA[4] := Point(2, 2);
- TPA[5] := Point(2, 2);
- TPAReplaceEx(TPA, [Point(0, 0), Point(1, 1)], Point(9, 9));
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPACreate"]
- [simba]{==============================================================================]
- Explanation: Creates TPA with pt (for every index) where size is length of the array.
- [==============================================================================}
- function TPACreate(pt: TPoint; size: Integer): TPointArray;
- var
- i: Integer;
- begin
- if (size > 0) then
- begin
- SetLength(Result, size);
- for i := 0 to (size - 1) do
- Result[i] := TPoint(pt);
- end else
- SetLength(Result, 0);
- end;
- var
- TPA: TPointArray;
- begin
- TPA := TPACreate(Point(6, 9), 5);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPACreateEx"]
- [simba]{==============================================================================]
- Explanation: Creates TPA with pts (for every index) where size is length of the array.
- [==============================================================================}
- function TPACreateEx(pts: TPointArray; size: Integer): TPointArray;
- var
- x, y: Integer;
- begin
- if (size > 0) then
- begin
- y := Length(pts);
- if (y = 0) then
- SetLength(Result, 0);
- SetLength(Result, size);
- if (y > 0) then
- for x := 0 to (size - 1) do
- Result[x] := TPoint(pts[(x mod y)]);
- end else
- SetLength(Result, 0);
- end;
- var
- TPA: TPointArray;
- begin
- TPA := TPACreateEx([Point(1, 2), Point(3, 4), Point(5, 6)], 10);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPABuild"]
- [simba]{==============================================================================]
- Explanation: Returns a TPA with xArr and yArr.
- If lengths of arrays aren't equal, then this function will use the one with smaller length.
- [==============================================================================}
- function TPABuild(xArr, yArr: TIntegerArray): TPointArray;
- var
- i, h: Integer;
- begin
- h := Min(High(xArr), High(yArr));
- SetLength(Result, (h + 1));
- for i := 0 to h do
- Result[i] := Point(xArr[i], yArr[i]);
- end;
- var
- TPA: TPointArray;
- begin
- TPA := TPABuild([10, 15, 20], [5, 10, 15]);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFromEllipseEx"]
- [simba]{==============================================================================]
- Explanation: Generates a TPA containing all coordinates within the given ellipse,
- defined by the center point and radius. Coordinates are stored row-by-row.
- [==============================================================================}
- function TPAFromEllipseEx(center: TPoint; XRadius, YRadius: Extended): TPointArray;
- var
- r, x, y, rx, ry: Integer;
- b: TBox;
- begin
- if ((XRadius > 0) and (YRadius > 0)) then
- begin
- rx := Round(XRadius);
- ry := Round(YRadius);
- b := IntToBox((center.X - rx), (center.Y - ry), (center.X + rx), (center.Y + ry));
- SetLength(Result, Integer(((b.X2 - b.X1) + 1) * ((b.Y2 - b.Y1) + 1)));
- for y := b.Y1 to b.Y2 do
- for x := b.X1 to b.X2 do
- if (Sqr((x - center.X) / XRadius) + Sqr((y - center.Y) / YRadius) <= 1) then
- begin
- Result[r] := Point(x, y);
- Inc(r);
- end;
- end;
- SetLength(Result, r);
- end;
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, b, w, h: Integer;
- begin
- b := High(TPA);
- if (b > -1) then
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- Exit;
- end;
- for a := 0 to b do
- if ((TPA[a].X > -1) and (TPA[a].Y > -1) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- var
- bmp: Integer;
- begin
- bmp := CreateBitmap(500, 500);
- SetPixels(bmp, TPAFromEllipseEx(Point(50, 50), 25.5, 20), 255);
- SetPixels(bmp, TPAFromEllipseEx(Point(250, 250), 50.5, 50.5), 16711680);
- SetPixels(bmp, TPAFromEllipseEx(Point(100, 250), 20.5, 10.5), 32768);
- SetPixels(bmp, TPAFromEllipseEx(Point(350, 100), 40.55, 15.444), 65535);
- SetPixels(bmp, TPAFromEllipseEx(Point(450, 350), 15, 45), 16777215);
- SetPixels(bmp, TPAFromEllipseEx(Point(60, 400), 35, 45), 8421504);
- SetPixels(bmp, TPAFromEllipseEx(Point(270, 420), 30, 30), 8388736);
- DisplayDebugImgWindow(500, 500);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFromCircleEx"]
- [simba]{==============================================================================]
- Explanation: Generates a TPA containing all coordinates within the given circle,
- defined by the center point and radius. Coordinates are stored row-by-row.
- [==============================================================================}
- function TPAFromCircleEx(center: TPoint; radius: Extended): TPointArray;
- var
- r, x, y, v: Integer;
- b: TBox;
- begin
- if (radius > 0) then
- begin
- v := Round(radius);
- b := IntToBox((center.X - v), (center.Y - v), (center.X + v), (center.Y + v));
- SetLength(Result, Integer(((b.X2 - b.X1) + 1) * ((b.Y2 - b.Y1) + 1)));
- for y := b.Y1 to b.Y2 do
- for x := b.X1 to b.X2 do
- if (Sqr((x - center.X) / radius) + Sqr((y - center.Y) / radius) <= 1) then
- begin
- Result[r] := Point(x, y);
- Inc(r);
- end;
- end;
- SetLength(Result, r);
- end;
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, b, w, h: Integer;
- begin
- b := High(TPA);
- if (b > -1) then
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- Exit;
- end;
- for a := 0 to b do
- if ((TPA[a].X > -1) and (TPA[a].Y > -1) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- var
- bmp: Integer;
- begin
- bmp := CreateBitmap(500, 500);
- SetPixels(bmp, TPAFromCircleEx(Point(50, 50), 25.5), 255);
- SetPixels(bmp, TPAFromCircleEx(Point(250, 250), 50.5), 16711680);
- SetPixels(bmp, TPAFromCircleEx(Point(100, 250), 20.5), 32768);
- SetPixels(bmp, TPAFromCircleEx(Point(350, 100), 30.444), 65535);
- SetPixels(bmp, TPAFromCircleEx(Point(450, 350), 45), 16777215);
- SetPixels(bmp, TPAFromCircleEx(Point(60, 400), 18.12), 8421504);
- SetPixels(bmp, TPAFromCircleEx(Point(270, 420), 30.9), 8388736);
- DisplayDebugImgWindow(500, 500);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFill"]
- [simba]{==============================================================================]
- Explanation: Fills whole TPA with pt.
- [==============================================================================}
- procedure TPAFill(var TPA: TPointArray; pt: TPoint);
- var
- h, i: Integer;
- begin
- h := High(TPA);
- for i := 0 to h do
- TPA[i] := TPoint(pt);
- end;
- var
- TPA: TPointArray;
- begin
- SetLength(TPA, 10);
- TPAFill(TPA, Point(6, 9));
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFillEx"]
- [simba]{==============================================================================]
- Explanation: Fills whole TPA with x.
- [==============================================================================}
- procedure TPAFillEx(var TPA: TPointArray; x: TPointArray);
- var
- i, h, l: Integer;
- begin
- h := High(TPA);
- l := Length(x);
- for i := 0 to h do
- TPA[i] := TPoint(x[(i mod l)]);
- end;
- var
- TPA: TPointArray;
- begin
- SetLength(TPA, 13);
- TPAFillEx(TPA, [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)]);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFillIDs"]
- [simba]{==============================================================================]
- Explanation: Fills TPA indexes (IDs) with pt.
- [==============================================================================}
- procedure TPAFillIDs(var TPA: TPointArray; IDs: TIntegerArray; pt: TPoint);
- var
- h, l, i: Integer;
- begin
- l := Length(TPA);
- h := High(IDs);
- if ((l > 0) and (h > -1)) then
- for i := 0 to h do
- if ((IDs[i] < l) and (IDs[i] > -1)) then
- TPA[IDs[i]] := TPoint(pt);
- end;
- var
- TPA: TPointArray;
- begin
- SetLength(TPA, 13);
- TPAFillIDs(TPA, [0, 1, 2, 6, 10, 11, 12], Point(6, 9));
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFillIDsEx"]
- [simba]{==============================================================================]
- Explanation: Fills TPA indexes (IDs) with pts.
- [==============================================================================}
- procedure TPAFillIDsEx(var TPA: TPointArray; IDs: TIntegerArray; pts: TPointArray);
- var
- h, l, i, m, r: Integer;
- begin
- l := Length(TPA);
- h := High(IDs);
- m := Length(pts);
- if ((l > 0) and (h > -1) and (m > 0)) then
- for i := 0 to h do
- if ((IDs[i] < l) and (IDs[i] > -1)) then
- begin
- TPA[IDs[i]] := TPoint(pts[(r mod m)]);
- Inc(r);
- end;
- end;
- var
- TPA: TPointArray;
- begin
- SetLength(TPA, 13);
- TPAFillIDsEx(TPA, [0, 1, 2, 6, 10, 11, 12], [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)]);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAXValues"]
- [simba]{==============================================================================]
- Explanation: Returns all the x-values of TPA.
- [==============================================================================}
- function TPAXValues(TPA: TPointArray): TIntegerArray;
- var
- h, i: Integer;
- begin
- h := High(TPA);
- SetLength(Result, (h + 1));
- for i := 0 to h do
- Result[i] := Integer(TPA[i].X);
- end;
- begin
- WriteLn(ToStr(TPAXValues(TPAFromBox(IntToBox(1, 1, 3, 3)))));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAYValues"]
- [simba]{==============================================================================]
- Explanation: Returns all the y-values of TPA.
- [==============================================================================}
- function TPAYValues(TPA: TPointArray): TIntegerArray;
- var
- h, i: Integer;
- begin
- h := High(TPA);
- SetLength(Result, (h + 1));
- for i := 0 to h do
- Result[i] := Integer(TPA[i].Y);
- end;
- begin
- WriteLn(ToStr(TPAYValues(TPAFromBox(IntToBox(1, 1, 3, 3)))));
- end.[/simba]
- [/spoiler]
- [spoiler="TPASwapValues"]
- [simba]
- procedure TPASwapValues(var TPA: TPointArray);
- var
- h, i, t: Integer;
- begin
- h := High(TPA);
- for i := 0 to h do
- begin
- t := TPA[i].X;
- TPA[i].X := TPA[i].Y;
- TPA[i].Y := t;
- end;
- end;
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, b, w, h: Integer;
- begin
- b := High(TPA);
- if (b > -1) then
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- Exit;
- end;
- for a := 0 to b do
- if ((TPA[a].X > -1) and (TPA[a].Y > -1) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- {==============================================================================]
- Explanation: Returns the line of points fromPt => toPt.
- [==============================================================================}
- function GetTPALine(fromPt, toPt: TPoint): TPointArray;
- var
- i, h: integer;
- begin
- if ((fromPt.X <> toPt.X) or (fromPt.Y <> toPt.Y)) then
- begin
- h := Max(Round(Abs(fromPt.X - toPt.X)), Round(Abs(fromPt.Y - toPt.Y)));
- SetLength(Result, (h + 1));
- for i := 0 to h do
- Result[i] := Point((fromPt.X + Round((toPt.X - fromPt.X) * (Extended(i) / h))), (fromPt.Y + Round((toPt.Y - fromPt.Y) * (Extended(i) / h))));
- end else
- Result := [fromPt];
- end;
- var
- i, l: Integer;
- bmp: Integer;
- TPA: TPointArray;
- begin
- bmp := CreateBitmap(500, 500);
- DisplayDebugImgWindow(500, 500);
- TPA := GetTPALine(Point(200, 200), Point(250, 300));
- SetPixels(bmp, TPA, clBlue);
- TPASwapValues(TPA);
- SetPixels(bmp, TPA, clRed);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPADensity"]
- [simba]{==============================================================================]
- Explanation: Returns the calculated density from given TPA.
- [==============================================================================}
- function TPADensity(TPA: TPointArray): Extended;
- var
- h, l, i, d, x, y: Integer;
- b: TBox;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- b := IntToBox(TPA[0].X, TPA[0].Y, TPA[0].X, TPA[0].Y);
- if (h > 0) then
- for i := (h - d) downto 1 do
- begin
- if (TPA[i].X < b.X1) then
- b.X1 := TPA[i].X
- else
- if (TPA[i].X > b.X2) then
- b.X2 := TPA[i].X;
- if (TPA[i].Y < b.Y1) then
- b.Y1 := TPA[i].Y
- else
- if (TPA[i].Y > b.Y2) then
- b.Y2 := TPA[i].Y;
- for x := (i - 1) downto 0 do
- if ((TPA[i].X = TPA[x].X) and (TPA[i].Y = TPA[x].Y)) then
- begin
- l := High(TPA);
- for y := i to (l - 1) do
- TPA[y] := TPA[(y + 1)];
- SetLength(TPA, l);
- Inc(d);
- Break;
- end;
- end;
- Result := (Extended(Length(TPA)) / (((b.X2 - b.X1) + 1) * ((b.Y2 - b.Y1) + 1)));
- end else
- Result := 0;
- end;
- var
- TPA: TPointArray;
- x, y: Integer;
- begin
- ClearDebug;
- for x := 0 to 2 do
- for y := 0 to 2 do
- begin
- AppendTPA(TPA, [Point(x, y)]);
- WriteLn('TPA Density: ' + FloatToStr(TPADensity(TPA)) + ' [' + ToStr(TPA) + ']');
- end;
- end.[/simba]
- [/spoiler]
- [spoiler="TPACenter"]
- [simba]{==============================================================================]
- Explanation: Returns the center point by TPA bounds as TPoint.
- [==============================================================================}
- function TPACenter(TPA: TPointArray): TPoint;
- var
- h, i: Integer;
- b: TBox;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- b := IntToBox(TPA[0].X, TPA[0].Y, TPA[0].X, TPA[0].Y);
- if (h > 0) then
- for i := 1 to h do
- begin
- if (TPA[i].X < b.X1) then
- b.X1 := TPA[i].X
- else
- if (TPA[i].X > b.X2) then
- b.X2 := TPA[i].X;
- if (TPA[i].Y < b.Y1) then
- b.Y1 := TPA[i].Y
- else
- if (TPA[i].Y > b.Y2) then
- b.Y2 := TPA[i].Y;
- end;
- Result := Point(Round(b.X1 + ((b.X2 - b.X1) div 2)), Round(b.Y1 + ((b.Y2 - b.Y1) div 2)));
- end else
- Result := Point(0, 0);
- end;
- var
- TPA: TPointArray;
- begin
- TPA := [Point(1, 1), Point(3, 5)];
- WriteLn(TPACenter(TPA));
- WriteLn(MiddleTPA(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAExtractEveryX"]
- [simba]{==============================================================================]
- Explanation: Extracts every X point from TPA.
- [==============================================================================}
- procedure TPAExtractEveryX(var TPA: TPointArray; X: Integer);
- var
- i, h, t: Integer;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- if (X > 0) then
- for i := 0 to h do
- if ((i mod X) = 0) then
- begin
- TPA[t] := TPA[i];
- Inc(t);
- end;
- SetLength(TPA, t);
- end;
- end;
- var
- TPA, tmp: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 0), Point(1, 1), Point(2, 2), Point(3, 3), Point(4, 4),
- Point(5, 5), Point(6, 6), Point(7, 7), Point(8, 8), Point(9, 9)];
- for i := 0 to 11 do
- begin
- tmp := CopyTPA(TPA);
- TPAExtractEveryX(tmp, i);
- WriteLn('TPAExtractEveryX(TPA, ' + IntToStr(i) + '): ' + ToStr(tmp));
- SetLength(tmp, 0);
- end;
- SetLength(TPA, 0);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAExtractEveryXEx"]
- [simba]{==============================================================================]
- Explanation: Extracts every X point from TPA - starting from offset.
- [==============================================================================}
- procedure TPAExtractEveryXEx(var TPA: TPointArray; X, offset: Integer);
- var
- i, h, t: Integer;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- if ((X > 0) and ((offset > -1) and (offset <= h))) then
- for i := offset to h do
- if (((i - offset) mod X) = 0) then
- begin
- TPA[t] := TPA[i];
- Inc(t);
- end;
- SetLength(TPA, t);
- end;
- end;
- var
- TPA, tmp: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 0), Point(1, 1), Point(2, 2), Point(3, 3), Point(4, 4),
- Point(5, 5), Point(6, 6), Point(7, 7), Point(8, 8), Point(9, 9)];
- for i := 0 to 9 do
- begin
- tmp := CopyTPA(TPA);
- TPAExtractEveryXEx(tmp, i, 2);
- WriteLn('TPAExtractEveryX(TPA, ' + IntToStr(i) + ', 2): ' + ToStr(tmp));
- SetLength(tmp, 0);
- end;
- SetLength(TPA, 0);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFilterEveryX"]
- [simba]{==============================================================================]
- Explanation: Filters every X point from TPA.
- [==============================================================================}
- procedure TPAFilterEveryX(var TPA: TPointArray; X: Integer);
- var
- i, h, t: Integer;
- begin
- h := High(TPA);
- if ((h > -1) and (X > 0)) then
- begin
- for i := 0 to h do
- if ((i mod X) <> 0) then
- begin
- TPA[t] := TPA[i];
- Inc(t);
- end;
- SetLength(TPA, t);
- end;
- end;
- var
- TPA, tmp: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 0), Point(1, 1), Point(2, 2), Point(3, 3), Point(4, 4),
- Point(5, 5), Point(6, 6), Point(7, 7), Point(8, 8), Point(9, 9)];
- for i := 0 to 6 do
- begin
- tmp := CopyTPA(TPA);
- TPAFilterEveryX(tmp, i);
- WriteLn('TPAFilterEveryX(TPA, ' + IntToStr(i) + '): ' + ToStr(tmp));
- SetLength(tmp, 0);
- end;
- SetLength(TPA, 0);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFilterEveryXEx"]
- [simba]{==============================================================================]
- Explanation: Filters every X point from TPA - starting from offset.
- [==============================================================================}
- procedure TPAFilterEveryXEx(var TPA: TPointArray; X, offset: Integer);
- var
- i, h, t: Integer;
- begin
- h := High(TPA);
- if ((h > -1) and (X > 0) and ((offset > -1) and (offset <= h))) then
- begin
- t := offset;
- for i := offset to h do
- if (((i - offset) mod X) <> 0) then
- begin
- TPA[t] := TPA[i];
- Inc(t);
- end;
- SetLength(TPA, t);
- end;
- end;
- var
- TPA, tmp: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 0), Point(1, 1), Point(2, 2), Point(3, 3), Point(4, 4),
- Point(5, 5), Point(6, 6), Point(7, 7), Point(8, 8), Point(9, 9)];
- for i := 0 to 9 do
- begin
- tmp := CopyTPA(TPA);
- TPAFilterEveryXEx(tmp, i, 2);
- WriteLn('TPAFilterEveryXEx(TPA, ' + IntToStr(i) + ', 2): ' + ToStr(tmp));
- SetLength(tmp, 0);
- end;
- SetLength(TPA, 0);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAExtractBoxes"]
- [simba]{==============================================================================]
- Explanation: Keeps all points in TPA that are found inside ANY box from boxes.
- [==============================================================================}
- procedure TPAExtractBoxes(var TPA: TPointArray; boxes: TBoxArray);
- var
- a, b, c, x, y: Integer;
- begin
- b := High(TPA);
- y := High(boxes);
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- begin
- for x := 0 to y do
- if ((TPA[a].X >= boxes[x].X1) and (TPA[a].Y >= boxes[x].Y1) and (TPA[a].X <= boxes[x].X2) and (TPA[a].Y <= boxes[x].Y2)) then
- Break;
- if (x <= y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA: TPointArray;
- filter: TBoxArray;
- bmp: Integer;
- i, h: Integer;
- begin
- filter := [IntToBox(150, 150, 175, 175), IntToBox(110, 120, 115, 125), IntToBox(100, 100, 103, 103), IntToBox(190, 100, 200, 125)];
- TPA := TPAFromBox(IntToBox(100, 100, 200, 200));
- TPAExtractBoxes(TPA, filter);
- bmp := CreateBitmap(500, 500);
- DisplayDebugImgWindow(500, 500);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 255);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFilterBoxes"]
- [simba]{==============================================================================]
- Explanation: Removes all points from TPA that are found inside ANY box from boxes.
- [==============================================================================}
- procedure TPAFilterBoxes(var TPA: TPointArray; boxes: TBoxArray);
- var
- a, b, c, x, y: Integer;
- begin
- b := High(TPA);
- y := High(boxes);
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- begin
- for x := 0 to y do
- if ((TPA[a].X >= boxes[x].X1) and (TPA[a].Y >= boxes[x].Y1) and (TPA[a].X <= boxes[x].X2) and (TPA[a].Y <= boxes[x].Y2)) then
- Break;
- if (x > y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA: TPointArray;
- filter: TBoxArray;
- bmp: Integer;
- i, h: Integer;
- begin
- filter := [IntToBox(150, 150, 175, 175), IntToBox(110, 120, 115, 125), IntToBox(100, 100, 103, 103), IntToBox(190, 100, 200, 125)];
- TPA := TPAFromBox(IntToBox(100, 100, 200, 200));
- TPAFilterBoxes(TPA, filter);
- bmp := CreateBitmap(500, 500);
- DisplayDebugImgWindow(500, 500);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 255);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAExtractPoints"]
- [simba]{==============================================================================]
- Explanation: Keeps all points in TPA that are found in points.
- [==============================================================================}
- procedure TPAExtractPoints(var TPA: TPointArray; points: TPointArray);
- var
- a, b, c, x, y: Integer;
- begin
- b := High(TPA);
- y := High(points);
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- begin
- for x := 0 to y do
- if ((TPA[a].X = points[x].X) and (TPA[a].Y = points[x].Y)) then
- Break;
- if (x <= y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA, filter: TPointArray;
- bmp: Integer;
- i, h: Integer;
- begin
- filter := [Point(105, 105), Point(195, 195), Point(105, 195), Point(195, 105)];
- TPA := TPAFromBox(IntToBox(100, 100, 200, 200));
- TPAExtractPoints(TPA, filter);
- bmp := CreateBitmap(500, 500);
- DisplayDebugImgWindow(500, 500);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFilterPoints"]
- [simba]{==============================================================================]
- Explanation: Removes all points from TPA that are found in points.
- [==============================================================================}
- procedure TPAFilterPoints(var TPA: TPointArray; points: TPointArray);
- var
- a, b, c, x, y: Integer;
- begin
- b := High(TPA);
- y := High(points);
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- begin
- for x := 0 to y do
- if ((TPA[a].X = points[x].X) and (TPA[a].Y = points[x].Y)) then
- Break;
- if (x > y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA, filter: TPointArray;
- bmp: Integer;
- i, h: Integer;
- begin
- filter := [Point(105, 105), Point(195, 195), Point(105, 195), Point(195, 105)];
- TPA := TPAFromBox(IntToBox(100, 100, 200, 200));
- TPAFilterPoints(TPA, filter);
- bmp := CreateBitmap(500, 500);
- DisplayDebugImgWindow(500, 500);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAExtractNearbyPoints"]
- [simba]{==============================================================================]
- Explanation: Keeps all points in TPA that are within distance from targets.
- [==============================================================================}
- procedure TPAExtractNearbyPoints(var TPA: TPointArray; targets: TPointArray; distance: Extended);
- var
- a, b, c, x, y: Integer;
- begin
- b := High(TPA);
- y := High(targets);
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- begin
- for x := 0 to y do
- if (distance >= Sqrt(Sqr(TPA[a].X - targets[x].X) + Sqr(TPA[a].Y - targets[x].Y))) then
- Break;
- if (x <= y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA, nearby: TPointArray;
- bmp: Integer;
- i, h: Integer;
- begin
- nearby := [Point(25, 25), Point(50, 50), Point(75, 75)];
- TPA := TPAFromBox(IntToBox(0, 0, 99, 99));
- TPAExtractNearbyPoints(TPA, nearby, 10);
- WriteLn(ToStr(TPA));
- bmp := CreateBitmap(100, 100);
- DisplayDebugImgWindow(100, 100);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAExtractNearbyPointsEx"]
- [simba]{==============================================================================]
- Explanation: Keeps all points in TPA that are within distance range (minDistance, maxDistance) from targets.
- [==============================================================================}
- procedure TPAExtractNearbyPointsEx(var TPA: TPointArray; targets: TPointArray; minDistance, maxDistance: Extended);
- var
- a, b, c, x, y: Integer;
- d: Extended;
- begin
- b := High(TPA);
- y := High(targets);
- if ((b > -1) and (y > -1)) then
- begin
- if (minDistance > maxDistance) then
- Swap(minDistance, maxDistance);
- for a := 0 to b do
- begin
- for x := 0 to y do
- begin
- d := Sqrt(Sqr(TPA[a].X - targets[x].X) + Sqr(TPA[a].Y - targets[x].Y));
- if ((d >= minDistance) and (d <= maxDistance)) then
- Break;
- end;
- if (x <= y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA, nearby: TPointArray;
- bmp: Integer;
- i, h: Integer;
- begin
- nearby := [Point(25, 25), Point(50, 50), Point(75, 75)];
- TPA := TPAFromBox(IntToBox(0, 0, 99, 99));
- TPAExtractNearbyPointsEx(TPA, nearby, 5, 10);
- WriteLn(ToStr(TPA));
- bmp := CreateBitmap(100, 100);
- DisplayDebugImgWindow(100, 100);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFilterNearbyPoints"]
- [simba]{==============================================================================]
- Explanation: Removes all points from TPA that are within distance from targets.
- [==============================================================================}
- procedure TPAFilterNearbyPoints(var TPA: TPointArray; targets: TPointArray; distance: Extended);
- var
- a, b, c, x, y: Integer;
- begin
- b := High(TPA);
- y := High(targets);
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- begin
- for x := 0 to y do
- if (distance >= Sqrt(Sqr(TPA[a].X - targets[x].X) + Sqr(TPA[a].Y - targets[x].Y))) then
- Break;
- if (x > y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA, nearby: TPointArray;
- bmp: Integer;
- i, h: Integer;
- begin
- nearby := [Point(25, 25), Point(50, 50), Point(75, 75)];
- TPA := TPAFromBox(IntToBox(0, 0, 99, 99));
- TPAFilterNearbyPoints(TPA, nearby, 10);
- WriteLn(ToStr(TPA));
- bmp := CreateBitmap(100, 100);
- DisplayDebugImgWindow(100, 100);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAFilterNearbyPointsEx"]
- [simba]{==============================================================================]
- Explanation: Removes all points from TPA that are within distance range (minDistance, maxDistance) from targets.
- [==============================================================================}
- procedure TPAFilterNearbyPointsEx(var TPA: TPointArray; targets: TPointArray; minDistance, maxDistance: Extended);
- var
- a, b, c, x, y: Integer;
- d: Extended;
- begin
- b := High(TPA);
- y := High(targets);
- if ((b > -1) and (y > -1)) then
- begin
- if (minDistance > maxDistance) then
- Swap(minDistance, maxDistance);
- for a := 0 to b do
- begin
- for x := 0 to y do
- begin
- d := Sqrt(Sqr(TPA[a].X - targets[x].X) + Sqr(TPA[a].Y - targets[x].Y));
- if ((d >= minDistance) and (d <= maxDistance)) then
- Break;
- end;
- if (x > y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- TPA, nearby: TPointArray;
- bmp: Integer;
- i, h: Integer;
- begin
- nearby := [Point(25, 25), Point(50, 50), Point(75, 75)];
- TPA := TPAFromBox(IntToBox(0, 0, 99, 99));
- TPAFilterNearbyPointsEx(TPA, nearby, 5, 10);
- WriteLn(ToStr(TPA));
- bmp := CreateBitmap(100, 100);
- DisplayDebugImgWindow(100, 100);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DrawBitmapDebugImg(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPASetConstraints"]
- [simba]{==============================================================================]
- Explanation: Sets ALL the points from TPA inside a TBox (area), if they are not inside it.
- Returns true if constraints were set to TPA (if any of the points in TPA was changed).
- [==============================================================================}
- function TPASetConstraints(var TPA: TPointArray; area: TBox): Boolean;
- var
- h, i: Integer;
- tmp: TPoint;
- begin
- h := High(TPA);
- Result := False;
- for i := 0 to h do
- begin
- if not Result then
- tmp := TPoint(TPA[i]);
- if (TPA[i].X < area.X1) then
- TPA[i].X := Integer(area.X1)
- else
- if (TPA[i].X > area.X2) then
- TPA[i].X := Integer(area.X2);
- if (TPA[i].Y < area.Y1) then
- TPA[i].Y := Integer(area.Y1)
- else
- if (TPA[i].Y > area.Y2) then
- TPA[i].Y := Integer(area.Y2);
- if (not Result and ((TPA[i].X <> tmp.X) or (TPA[i].Y <> tmp.Y))) then
- Result := True;
- end;
- end;
- var
- TPA: TPointArray;
- begin
- TPA := [Point(9, 10), Point(9, 9), Point(10, 9), Point(50, 50), Point(100, 99), Point(100, 100), Point(99, 100)];
- if TPASetConstraints(TPA, IntToBox(10, 10, 99, 99)) then
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAUnusedBoxPixels"]
- [simba]{==============================================================================]
- Explanation: Explanation: Returns all the points from box (bx) that aren't used in TPA.
- [==============================================================================}
- function TPAUnusedBoxPixels(TPA: TPointArray; bx: TBox): TPointArray;
- var
- v, x, y, h, r: Integer;
- B: array of TBoolArray;
- begin;
- h := High(TPA);
- if ((h > -1) and ((((bx.X2 - bx.X1) + 1) > 0) and (((bx.Y2 - bx.Y1) + 1) > 0))) then
- begin
- SetLength(B, ((bx.X2 - bx.X1) + 1));
- for v := 0 to (bx.X2 - bx.X1) do
- SetLength(B[v], ((bx.Y2 - bx.Y1) + 1));
- for v := 0 to h do
- if ((TPA[v].X >= bx.X1) and (TPA[v].Y >= bx.Y1) and (TPA[v].X <= bx.X2) and (TPA[v].Y <= bx.Y2)) then
- if not B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] then
- begin
- B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] := True;
- Inc(x);
- end;
- SetLength(Result, ((((bx.X2 - bx.X1) + 1) * ((bx.Y2 - bx.Y1) + 1)) - x));
- if (Length(Result) > 0) then
- for y := 0 to (bx.Y2 - bx.Y1) do
- for x := 0 to (bx.X2 - bx.X1) do
- if not B[x][y] then
- begin
- Result[r].X := (x + bx.X1);
- Result[r].Y := (y + bx.Y1);
- Inc(r);
- end;
- SetLength(B, 0);
- end else
- SetLength(Result, 0);
- end;
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, b, w, h: Integer;
- begin
- b := High(TPA);
- if (b > -1) then
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- Exit;
- end;
- for a := 0 to b do
- if ((TPA[a].X > -1) and (TPA[a].Y > -1) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- var
- TPA: TPointArray;
- bmp: Integer;
- begin
- ClearDebug;
- TPA := TPAUnusedBoxPixels(TPAFromBox(IntToBox(0, 0, 40, 40)), IntToBox(25, 25, 75, 75));
- bmp := CreateBitmap(100, 100);
- SetPixels(bmp, TPA, clRed);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAUsedBoxPixels"]
- [simba]{==============================================================================]
- Explanation: Returns all the points from box (bx) that aren't used in TPA.
- [==============================================================================}
- function TPAUsedBoxPixels(TPA: TPointArray; bx: TBox): TPointArray;
- var
- v, x, y, h, r: Integer;
- B: array of TBoolArray;
- begin;
- h := High(TPA);
- if ((h > -1) and ((((bx.X2 - bx.X1) + 1) > 0) and (((bx.Y2 - bx.Y1) + 1) > 0))) then
- begin
- SetLength(B, ((bx.X2 - bx.X1) + 1));
- for v := 0 to (bx.X2 - bx.X1) do
- SetLength(B[v], ((bx.Y2 - bx.Y1) + 1));
- for v := 0 to h do
- if ((TPA[v].X >= bx.X1) and (TPA[v].Y >= bx.Y1) and (TPA[v].X <= bx.X2) and (TPA[v].Y <= bx.Y2)) then
- if not B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] then
- begin
- B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] := True;
- Inc(x);
- end;
- if (x > 0) then
- begin
- SetLength(Result, x);
- for y := 0 to (bx.Y2 - bx.Y1) do
- for x := 0 to (bx.X2 - bx.X1) do
- if B[x][y] then
- begin
- Result[r].X := (x + bx.X1);
- Result[r].Y := (y + bx.Y1);
- Inc(r);
- end;
- end;
- SetLength(Result, r);
- SetLength(B, 0);
- end else
- SetLength(Result, 0);
- end;
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, b, w, h: Integer;
- begin
- b := High(TPA);
- if (b > -1) then
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- Exit;
- end;
- for a := 0 to b do
- if ((TPA[a].X > -1) and (TPA[a].Y > -1) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- var
- TPA: TPointArray;
- bmp: Integer;
- begin
- ClearDebug;
- TPA := TPAUsedBoxPixels(TPAFromBox(IntToBox(0, 0, 40, 40)), IntToBox(25, 25, 75, 75));
- bmp := CreateBitmap(100, 100);
- SetPixels(bmp, TPA, 255);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAReverse"]
- [simba]{==============================================================================]
- Explanation: Reverses TPA.
- [==============================================================================}
- procedure TPAReverse(var TPA: TPointArray);
- var
- g, h, i: Integer;
- begin
- h := High(TPA);
- if (h < 1) then
- Exit;
- g := (h div 2);
- for i := 0 to g do
- Swap(TPA[i], TPA[(h - i)]);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- TPAReverse(TPA);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAInvert"]
- [simba]{==============================================================================]
- Explanation: Inverts TPA by replacing all of the points inside the bounds that weren't defined in the array.
- [==============================================================================}
- procedure TPAInvert(var TPA: TPointArray);
- var
- v, x, y, h, r: Integer;
- B: array of TBoolArray;
- bx: TBox;
- begin;
- h := High(TPA);
- if (h > 0) then
- begin
- bx := IntToBox(TPA[0].X, TPA[0].Y, TPA[0].X, TPA[0].Y);
- for v := 1 to h do
- begin
- if (TPA[v].X < bx.X1) then
- bx.X1 := TPA[v].X
- else
- if (TPA[v].X > bx.X2) then
- bx.X2 := TPA[v].X;
- if (TPA[v].Y < bx.Y1) then
- bx.Y1 := TPA[v].Y
- else
- if (TPA[v].Y > bx.Y2) then
- bx.Y2 := TPA[v].Y;
- end;
- SetLength(B, ((bx.X2 - bx.X1) + 1));
- for v := 0 to (bx.X2 - bx.X1) do
- SetLength(B[v], ((bx.Y2 - bx.Y1) + 1));
- for v := 0 to h do
- if not B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] then
- begin
- B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] := True;
- Inc(x);
- end;
- SetLength(TPA, ((((bx.X2 - bx.X1) + 1) * ((bx.Y2 - bx.Y1) + 1)) - x));
- if (Length(TPA) > 0) then
- for y := 0 to (bx.Y2 - bx.Y1) do
- for x := 0 to (bx.X2 - bx.X1) do
- if not B[x][y] then
- begin
- TPA[r].X := (x + bx.X1);
- TPA[r].Y := (y + bx.Y1);
- Inc(r);
- end;
- SetLength(B, 0);
- end else
- SetLength(TPA, 0);
- end;
- var
- bmp: Integer;
- TPA: TPointArray;
- h, i: Integer;
- begin
- ClearDebug;
- TPA := [Point(25, 25), Point(75, 75)];
- h := High(TPA);
- bmp := CreateBitmap(100, 100);
- TPAInvert(TPA);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAEdge"]
- [simba]{==============================================================================]
- Explanation: Replaces TPA with all the edge-points from TPA.
- Edge-points are points that are on the edge of the TPA, not completely surrounded by other points.
- [==============================================================================}
- procedure TPAEdge(var TPA: TPointArray);
- var
- v, x, y, h, r: Integer;
- B: array of TBoolArray;
- bx: TBox;
- begin;
- h := High(TPA);
- if (h > 3) then
- begin
- bx := IntToBox(TPA[0].X, TPA[0].Y, TPA[0].X, TPA[0].Y);
- for v := 1 to h do
- begin
- if (TPA[v].X < bx.X1) then
- bx.X1 := TPA[v].X
- else
- if (TPA[v].X > bx.X2) then
- bx.X2 := TPA[v].X;
- if (TPA[v].Y < bx.Y1) then
- bx.Y1 := TPA[v].Y
- else
- if (TPA[v].Y > bx.Y2) then
- bx.Y2 := TPA[v].Y;
- end;
- bx := IntToBox((bx.X1 - 1), (bx.Y1 - 1), (bx.X2 + 1), (bx.Y2 + 1));
- SetLength(B, ((bx.X2 - bx.X1) + 1));
- for v := 0 to (bx.X2 - bx.X1) do
- SetLength(B[v], ((bx.Y2 - bx.Y1) + 1));
- for v := 0 to h do
- if not B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] then
- B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] := True;
- for y := 1 to ((bx.Y2 - bx.Y1) - 1) do
- for x := 1 to ((bx.X2 - bx.X1) - 1) do
- if B[x][y] then
- if not (B[(x - 1)][y] and B[x][(y - 1)] and B[(x + 1)][y] and B[x][(y + 1)]) then
- begin
- TPA[r].X := (x + bx.X1);
- TPA[r].Y := (y + bx.Y1);
- Inc(r);
- end;
- SetLength(TPA, r);
- SetLength(B, 0);
- end;
- end;
- {==============================================================================]
- Explanation: Removes all points from TPA that are found in points.
- [==============================================================================}
- procedure TPAFilterPoints(var TPA: TPointArray; points: TPointArray);
- var
- a, b, c, x, y: Integer;
- begin
- b := High(TPA);
- y := High(points);
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- begin
- for x := 0 to y do
- if ((TPA[a].X = points[x].X) and (TPA[a].Y = points[x].Y)) then
- Break;
- if (x > y) then
- begin
- TPA[c] := TPA[a];
- Inc(c);
- end;
- end;
- SetLength(TPA, c);
- end;
- var
- bmp: Integer;
- TPA: TPointArray;
- h, i: Integer;
- begin
- ClearDebug;
- TPA := TPAFromBox(IntToBox(25, 25, 50, 50));
- TPA[0] := Point(5, 5);
- TPA[High(TPA)] := Point(95, 95);
- TPAFilterPoints(TPA, [Point(36, 34), Point(47, 42)]);
- bmp := CreateBitmap(100, 100);
- TPAEdge(TPA);
- h := High(TPA);
- for i := 0 to h do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 16777215);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPARotate"]
- [simba]{==============================================================================]
- Explanation: Rotates all points in TPA around center by an angle (in radians).
- [==============================================================================}
- procedure TPARotate(var TPA: TPointArray; center: TPoint; angle: Extended);
- var
- h, i, x, y: Integer;
- c, s: Extended;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- c := Cos(angle);
- s := Sin(angle);
- for i := 0 to h do
- begin
- x := (TPA[i].X - center.X);
- y := (TPA[i].Y - center.Y);
- TPA[i].X := (Round((x * c) - (y * s)) + center.X);
- TPA[i].Y := (Round((x * s) + (y * c)) + center.Y);
- end;
- end;
- end;
- var
- TPA: TPointArray;
- bmp, i: Integer;
- begin
- ClearDebug;
- TPA := TPAFromBox(IntToBox(25, 25, 50, 50));
- TPARotate(TPA, Point(37, 37), Radians(45))
- bmp := CreateBitmap(100, 100);
- for i := 0 to High(TPA) do
- FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 255);
- SetLength(TPA, 0);
- DrawBitmapDebugImg(bmp);
- DisplayDebugImgWindow(100, 100);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAOffset"]
- [simba]{==============================================================================]
- Explanation: Offsets TPA using offset point.
- [==============================================================================}
- procedure TPAOffset(var TPA: TPointArray; offset: TPoint);
- var
- h, i: Integer;
- begin
- h := High(TPA);
- for i := 0 to h do
- begin
- TPA[i].X := (TPA[i].X + offset.X);
- TPA[i].Y := (TPA[i].Y + offset.Y);
- end;
- end;
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, b, w, h: Integer;
- begin
- b := High(TPA);
- if (b > -1) then
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- Exit;
- end;
- for a := 0 to b do
- if ((TPA[a].X > -1) and (TPA[a].Y > -1) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- var
- TPA: TPointArray;
- bmp: Integer;
- begin
- ClearDebug;
- TPA := TPAFromBox(IntToBox(0, 0, 9, 9));
- TPAOffset(TPA, Point(25, 25));
- WriteLn(ToStr(TPA));
- bmp := CreateBitmap(100, 100);
- SetPixels(bmp, TPA, clRed);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAOffsetEx"]
- [simba]{==============================================================================]
- Explanation: Offsets TPA using radius & angle (degrees).
- NOTE: Angle is based on COMPASS degrees: http://www.blackknightassociation.com/Images/acirclueis360degrees.jpg
- [==============================================================================}
- procedure TPAOffsetEx(var TPA: TPointArray; radius, angle: Extended);
- var
- h, i: Integer;
- begin
- h := High(TPA);
- for i := 0 to h do
- begin
- TPA[i].X := Round(radius * Sin(angle * (Pi / 180)) + TPA[i].X);
- TPA[i].Y := Round(-radius * Cos(angle * (Pi / 180)) + TPA[i].Y);
- end;
- end;
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, b, w, h: Integer;
- begin
- b := High(TPA);
- if (b > -1) then
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- Exit;
- end;
- for a := 0 to b do
- if ((TPA[a].X > -1) and (TPA[a].Y > -1) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- var
- TPA: TPointArray;
- bmp: Integer;
- begin
- ClearDebug;
- TPA := TPAFromBox(IntToBox(0, 0, 9, 9));
- TPAOffsetEx(TPA, 35, 135.0);
- WriteLn(ToStr(TPA));
- bmp := CreateBitmap(100, 100);
- SetPixels(bmp, TPA, clRed);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAUnique"]
- [simba]{==============================================================================]
- Explanation: Removes all duplicates from TPA.
- [==============================================================================}
- procedure TPAUnique(var TPA: TPointArray);
- var
- h, h2, i, i2, i3, d: Integer;
- begin
- h := High(TPA);
- if (h < 1) then
- Exit;
- for i := (h - d) downto 1 do
- for i2 := (i - 1) downto 0 do
- if ((TPA[i].X = TPA[i2].X) and (TPA[i].Y = TPA[i2].Y)) then
- begin
- h2 := High(TPA);
- for i3 := i to (h2 - 1) do
- TPA[i3] := TPA[(i3 + 1)];
- SetLength(TPA, h2);
- Inc(d);
- Break;
- end;
- end;
- var
- TPA: TPointArray;
- begin
- TPA := [Point(0, 0), Point(1, 1), Point(2, 2), Point(1, 1), Point(0, 0), Point(2, 2), Point(3, 3), Point(4, 4), Point(3, 3), Point(0, 0), Point(0, 0), Point(3, 3), Point(1, 1)];
- TPAUnique(TPA);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAUnique2"]
- [simba]{==============================================================================]
- Explanation: Removes all duplicates from TPA. Optimized by masterBB!
- [==============================================================================}
- procedure TPAUnique2(var TPA: TPointArray);
- var
- v, h, r: Integer;
- B: array of TBoolArray;
- bx: TBox;
- begin;
- h := High(TPA);
- if (h > 0) then
- begin
- bx := IntToBox(TPA[0].X, TPA[0].Y, TPA[0].X, TPA[0].Y);
- for v := 1 to h do
- begin
- if (TPA[v].X < bx.X1) then
- bx.X1 := TPA[v].X
- else
- if (TPA[v].X > bx.X2) then
- bx.X2 := TPA[v].X;
- if (TPA[v].Y < bx.Y1) then
- bx.Y1 := TPA[v].Y
- else
- if (TPA[v].Y > bx.Y2) then
- bx.Y2 := TPA[v].Y;
- end;
- SetLength(B, ((bx.X2 - bx.X1) + 1));
- for v := 0 to (bx.X2 - bx.X1) do
- SetLength(B[v], ((bx.Y2 - bx.Y1) + 1));
- for v := 0 to h do
- if not B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] then
- begin
- B[(TPA[v].X - bx.X1)][(TPA[v].Y - bx.Y1)] := True;
- TPA[r] := TPA[v];
- Inc(r);
- end;
- SetLength(TPA, r);
- SetLength(B, 0);
- end;
- end;
- var
- TPA: TPointArray;
- begin
- TPA := [Point(0, 0), Point(1, 1), Point(2, 2), Point(1, 1), Point(0, 0), Point(2, 2), Point(3, 3), Point(4, 4), Point(3, 3), Point(0, 0), Point(0, 0), Point(3, 3), Point(1, 1)];
- TPAUnique2(TPA);
- WriteLn(ToStr(TPA));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAUniqueIDs"]
- [simba]{==============================================================================]
- Explanation: Returns all indexes from TPA where the points are unique compared to other points in array.
- [==============================================================================}
- function TPAUniqueIDs(TPA: TPointArray): TIntegerArray;
- var
- h, r, x, y: Integer;
- begin
- h := High(TPA);
- SetLength(Result, (h + 1));
- if (h > -1) then
- if (h > 0) then
- begin
- for x := 0 to h do
- begin
- for y := 0 to h do
- if ((y <> x) and ((TPA[x].X = TPA[y].X) and (TPA[x].Y = TPA[y].Y))) then
- Break;
- if (y > h) then
- begin
- Result[r] := x;
- Inc(r);
- end;
- end;
- SetLength(Result, r);
- end else
- Result[0] := 0;
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(4, 5),
- Point(6, 7), Point(8, 9), Point(6, 7), Point(8, 9)];
- WriteLn(ToStr(TPAUniqueIDs(TPA)));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAGrid"]
- [simba]{==============================================================================]
- Explanation: Returns/builds grid of points with parameters;
- startPoint = start point of the grid
- rows, columns = count of rows and columns
- rowSpace, columnSpace = the space between points at rows and columns
- [==============================================================================}
- function TPAGrid(startPoint: TPoint; rows, columns, rowSpace, columnSpace: Integer): TPointArray;
- var
- r, c: Integer;
- begin
- if ((rows > 0) and (columns > 0) and ((rows * columns) > 0)) then
- begin
- SetLength(Result, (rows * columns));
- for r := 0 to (rows - 1) do
- for c := 0 to (columns - 1) do
- Result[((r * columns) + c)] := Point((startPoint.X + (c * columnSpace)), (startPoint.Y + (r * rowSpace)));
- end else
- SetLength(Result, 0);
- end;
- const
- START_X = 10;
- START_Y = 10;
- ROWS = 100;
- COLUMNS = 200;
- ROW_SPACE = 2;
- COLUMN_SPACE = 2;
- var
- TPA: TPointArray;
- b, i: Integer;
- begin
- b := CreateBitmap(500, 500);
- TPA := TPAGrid(Point(START_X, START_Y), ROWS, COLUMNS, ROW_SPACE, COLUMN_SPACE);
- for i := 0 to High(TPA) do
- FastSetPixel(b, TPA[i].X, TPA[i].Y, 16777215);
- SetLength(TPA, 0);
- DisplayDebugImgWindow(500, 500);
- DrawBitmapDebugImg(b);
- FreeBitmap(b);
- end.[/simba]
- [/spoiler]
- [spoiler="TPARow"]
- [simba]{==============================================================================]
- Explanation: Returns row of points. Starting from startPoint,
- where rowSpace is the amount of space between each point.
- NOTE: Example row = (0, 0), (0, 1), (0, 2), (0, 3), (0, 4) (rowSpace as 1)
- [==============================================================================}
- function TPARow(startPoint: TPoint; rows, rowSpace: Integer): TPointArray;
- var
- i: Integer;
- begin
- if (rows > 0) then
- begin
- SetLength(Result, rows);
- for i := 0 to (rows - 1) do
- Result[i] := Point(startPoint.X, (startPoint.Y + (i * rowSpace)));
- end else
- SetLength(Result, 0);
- end;
- const
- START_X = 10;
- START_Y = 10;
- ROWS = 100;
- ROW_SPACE = 4;
- var
- TPA: TPointArray;
- b, i: Integer;
- begin
- b := CreateBitmap(500, 500);
- TPA := TPARow(Point(START_X, START_Y), ROWS, ROW_SPACE);
- for i := 0 to High(TPA) do
- FastSetPixel(b, TPA[i].X, TPA[i].Y, 16777215);
- SetLength(TPA, 0);
- DisplayDebugImgWindow(500, 500);
- DrawBitmapDebugImg(b);
- FreeBitmap(b);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAColumn"]
- [simba]{==============================================================================]
- Explanation: Returns column of points. Starting from startPoint,
- where columnSpace is the amount of space between each point.
- NOTE: Example column = (0, 0), (1, 0), (2, 0), (3, 0), (4, 0) (columnSpace as 1)
- [==============================================================================}
- function TPAColumn(startPoint: TPoint; columns, columnSpace: Integer): TPointArray;
- var
- i: Integer;
- begin
- if (columns > 0) then
- begin
- SetLength(Result, columns);
- for i := 0 to (columns - 1) do
- Result[i] := Point((startPoint.X + (i * columnSpace)), startPoint.Y);
- end else
- SetLength(Result, 0);
- end;
- const
- START_X = 10;
- START_Y = 10;
- COLUMNS = 100;
- COLUMN_SPACE = 4;
- var
- TPA: TPointArray;
- b, i: Integer;
- begin
- b := CreateBitmap(500, 500);
- TPA := TPAColumn(Point(START_X, START_Y), COLUMNS, COLUMN_SPACE);
- for i := 0 to High(TPA) do
- FastSetPixel(b, TPA[i].X, TPA[i].Y, 16777215);
- SetLength(TPA, 0);
- DisplayDebugImgWindow(500, 500);
- DrawBitmapDebugImg(b);
- FreeBitmap(b);
- end.[/simba]
- [/spoiler]
- [spoiler="TPACombine"]
- [simba]{==============================================================================]
- Explanation: Returns TPA1 and TPA2 combined together.
- [==============================================================================}
- function TPACombine(TPA1, TPA2: TPointArray): TPointArray;
- var
- l1, l2, i: Integer;
- begin
- l1 := Length(TPA1);
- l2 := Length(TPA2);
- SetLength(Result, (l1 + l2));
- for i := 0 to (l1 - 1) do
- Result[i] := TPoint(TPA1[i]);
- for i := 0 to (l2 - 1) do
- Result[(l1 + i)] := TPoint(TPA2[i]);
- end;
- begin
- WriteLn(ToStr(TPACombine([Point(0, 1), Point(2, 3)], [Point(4, 5), Point(6, 7), Point(8, 9)])));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAContains"]
- [simba]{==============================================================================]
- Explanation: Returns true if TPA contains x.
- [==============================================================================}
- function TPAContains(TPA: TPointArray; x: TPoint): Boolean;
- var
- i, h: Integer;
- begin
- h := High(TPA);
- for i := 0 to h do
- begin
- Result := ((x.X = TPA[i].X) and (x.Y = TPA[i].Y));
- if Result then
- Exit;
- end;
- Result := False;
- end;
- var
- TPA: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- for i := -1 to 5 do
- if TPAContains(TPA, Point((i * 2), ((i * 2) + 1))) then
- WriteLn(ToStr('Point(' + IntToStr(i * 2) + ', ' + IntToStr((i * 2) + 1)) + ') exists in TPA!')
- else
- WriteLn(ToStr('Point(' + IntToStr(i * 2) + ', ' + IntToStr((i * 2) + 1)) + ') DOES NOT exist in TPA!');
- end.[/simba]
- [/spoiler]
- [spoiler="TPAContainsEx"]
- [simba]{==============================================================================]
- Explanation: Returns true if TPA contains ANY TPoint from pts.
- [==============================================================================}
- function TPAContainsEx(TPA, pts: TPointArray): Boolean;
- var
- a, b, x, y: Integer;
- begin
- b := High(TPA);
- y := High(pts);
- Result := True;
- if ((b > -1) and (y > -1)) then
- for a := 0 to b do
- for x := 0 to y do
- if ((TPA[a].X = pts[x].X) and (TPA[a].Y = pts[x].Y)) then
- Exit;
- Result := False;
- end;
- begin
- ClearDebug;
- if TPAContainsEx([Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)], [Point(8, 9), Point(4, 5)]) then
- WriteLn('YEP!');
- end.[/simba]
- [/spoiler]
- [spoiler="TPAContainsTPA"]
- [simba]{==============================================================================]
- Explanation: Returns true if TPA contains WHOLE chain of TPoints (arr) in it.
- [==============================================================================}
- function TPAContainsTPA(TPA, arr: TPointArray): Boolean;
- var
- a, b, x, y, z: Integer;
- begin
- z := High(TPA);
- y := High(arr);
- if ((z >= y) and (z > -1)) then
- begin
- b := (z - y);
- for a := 0 to b do
- begin
- for x := 0 to y do
- if ((TPA[(a + x)].X <> arr[x].X) or (TPA[(a + x)].Y <> arr[x].Y)) then
- Break;
- if (x > y) then
- Break;
- end;
- Result := (a <= b);
- end else
- Result := False;
- end;
- begin
- ClearDebug;
- if TPAContainsTPA([Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)], [Point(8, 9), Point(4, 5)]) then
- WriteLn('NOOOO!');
- if TPAContainsTPA([Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)], [Point(4, 5), Point(6, 7), Point(8, 9)]) then
- WriteLn('YEEAH!');
- end.[/simba]
- [/spoiler]
- [spoiler="TPAPos"]
- [simba]{==============================================================================]
- Explanation: Returns index position from TPA which matched with pt.
- Returns -1 if any of TPA items doesnt match with pt!
- [==============================================================================}
- function TPAPos(TPA: TPointArray; pt: TPoint): Integer;
- var
- h: Integer;
- begin
- h := High(TPA);
- for Result := 0 to h do
- if ((TPA[Result].X = pt.X) and (TPA[Result].Y = pt.Y)) then
- Exit;
- Result := -1;
- end;
- var
- TPA: TPointArray;
- i, p: Integer;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- for i := -1 to 5 do
- begin
- p := TPAPos(TPA, Point((i * 2), ((i * 2) + 1)));
- if (p > -1) then
- WriteLn(ToStr('Point(' + IntToStr(i * 2) + ', ' + IntToStr((i * 2) + 1)) + ') index in TPA: ' + IntToStr(p))
- else
- WriteLn(ToStr('Point(' + IntToStr(i * 2) + ', ' + IntToStr((i * 2) + 1)) + ') DOES NOT exist in TPA!');
- end;
- end.[/simba]
- [/spoiler]
- [spoiler="TPAEmpty"]
- [simba]{==============================================================================]
- Explanation: Returns true if TPA is empty (Length(TPA) = 0).
- [==============================================================================}
- function TPAEmpty(TPA: TPointArray): Boolean;
- begin
- Result := (Length(TPA) = 0);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- if TPAEmpty(TPA) then
- WriteLn('Yeah, TPA is still empty of points... Obviously!');
- SetLength(TPA, 1);
- if not TPAEmpty(TPA) then
- WriteLn('TPA is not empty anymore.');
- end.[/simba]
- [/spoiler]
- [spoiler="TPABounds"]
- [simba]{==============================================================================]
- Explanation: Returns the bounds of TPA as TBox.
- [==============================================================================}
- function TPABounds(TPA: TPointArray): TBox;
- var
- h, i: Integer;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- Result := IntToBox(TPA[0].X, TPA[0].Y, TPA[0].X, TPA[0].Y);
- if (h > 0) then
- for i := 1 to h do
- begin
- if (TPA[i].X < Result.X1) then
- Result.X1 := TPA[i].X
- else
- if (TPA[i].X > Result.X2) then
- Result.X2 := TPA[i].X;
- if (TPA[i].Y < Result.Y1) then
- Result.Y1 := TPA[i].Y
- else
- if (TPA[i].Y > Result.Y2) then
- Result.Y2 := TPA[i].Y;
- end;
- end else
- Result := IntToBox(0, 0, 0, 0);
- end;
- var
- TPA: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- TPA := TPAFromBox(IntToBox(100, 100, 200, 200));
- for i := 0 to High(TPA) do
- Swap(TPA[Random(Length(TPA))], TPA[Random(Length(TPA))]);
- WriteLn('TPABounds(TPA): ' + ToStr(TPABounds(TPA)));
- end.[/simba]
- [/spoiler]
- [spoiler="TPAMean"]
- [simba]{==============================================================================]
- Explanation: Returns the arithmetic mean point by TPA items.
- [==============================================================================}
- function TPAMean(TPA: TPointArray): TPoint;
- var
- i, h: Integer;
- x, y: Extended;
- begin
- h:= High(TPA);
- for i:= 0 to h do
- begin
- x := (x + (Extended(TPA[i].X) / (h + 1)));
- y := (y + (Extended(TPA[i].Y) / (h + 1)));
- end;
- Result := Point(Round(x), Round(y));
- end;
- var
- a, b: TPointArray;
- i: Integer;
- begin
- ClearDebug;
- a := TPAFromBox(IntToBox(0, 0, 9, 9));
- SetLength(b, 10);
- for i := 0 to 9 do
- b[i] := TPoint(a[Random(Length(a))]);
- WriteLn(ToStr(b) + ' => ' + ToStr(TPAMean(b)));
- end.[/simba]
- [/spoiler]
- [spoiler="TPASplitEx"]
- [simba]{==============================================================================]
- Explanation: Splits given TPointArray (TPA) into T2DPointArray by grouping together the point values
- that are within a given distance range (minDistance, maxDistance) from each other.
- [==============================================================================}
- function TPASplitEx(TPA: TPointArray; minDistance, maxDistance: Extended): T2DPointArray;
- var
- a, b, h, l, i, r: Integer;
- d: Extended;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- SetLength(Result, (h + 1));
- Result[0] := [TPoint(TPA[0])];
- if (h > 0) then
- begin
- r := 1;
- if (minDistance > maxDistance) then
- Swap(minDistance, maxDistance);
- for i := 1 to h do
- begin
- for a := 0 to (r - 1) do
- begin
- l := Length(Result[a]);
- for b := 0 to (l - 1) do
- begin
- d := Sqrt(Sqr(TPA[i].X - Result[a][b].X) + Sqr(TPA[i].Y - Result[a][b].Y));
- if ((d >= minDistance) and (d <= maxDistance)) then
- begin
- SetLength(Result[a], (l + 1));
- Result[a][l] := TPoint(TPA[i]);
- Break;
- end;
- end;
- if (b < l) then
- Break;
- end;
- if (a >= r) then
- begin
- Result[r] := [TPoint(TPA[i])];
- Inc(r);
- end;
- end;
- end;
- end;
- SetLength(Result, r);
- end;
- const
- MINIMUM_DIST = 0;
- MAXIMUM_DIST = 4;
- var
- color: TIntegerArray;
- TPA: TPointArray;
- ATPA: T2DPointArray;
- i, j, bmp: Integer;
- begin
- ClearDebug;
- TPA := [Point(5, 5), Point(3, 4), Point(15, 15), Point(18, 16), Point(4, 5), Point(14, 18),
- Point(78, 68), Point(75, 72), Point(74, 74), Point(6, 6), Point(79, 70), Point(20, 19)];
- ATPA := TPASplitEx(TPA, MINIMUM_DIST, MAXIMUM_DIST);
- WriteLn(ToStr(ATPA));
- color := [255, 16777215, 16711680, 65535, 32768, 8421504];
- bmp := CreateBitmap(100, 100);
- for i := 0 to High(ATPA) do
- for j := 0 to High(ATPA[i]) do
- FastSetPixel(bmp, ATPA[i][j].X, ATPA[i][j].Y, color[(i mod 6)]);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAGroupEx"]
- [simba]{==============================================================================]
- Explanation: Splits given TPointArray (TPA) into T2DPointArray by grouping together the point values
- that are within a given distance range (minDistance, maxDistance) of the first point value in the sub-array.
- [==============================================================================}
- function TPAGroupEx(TPA: TPointArray; minDistance, maxDistance: Extended): T2DPointArray;
- var
- a, h, l, i, r: Integer;
- d: Extended;
- begin
- h := High(TPA);
- if (h > -1) then
- begin
- SetLength(Result, (h + 1));
- Result[0] := [TPoint(TPA[0])];
- if (h > 0) then
- begin
- r := 1;
- if (minDistance > maxDistance) then
- Swap(minDistance, maxDistance);
- for i := 1 to h do
- begin
- for a := 0 to (r - 1) do
- begin
- d := Sqrt(Sqr(TPA[i].X - Result[a][0].X) + Sqr(TPA[i].Y - Result[a][0].Y));
- if ((d >= minDistance) and (d <= maxDistance)) then
- begin
- l := Length(Result[a]);
- SetLength(Result[a], (l + 1));
- Result[a][l] := TPoint(TPA[i]);
- Break;
- end;
- end;
- if (a >= r) then
- begin
- Result[r] := [TPoint(TPA[i])];
- Inc(r);
- end;
- end;
- end;
- end;
- SetLength(Result, r);
- end;
- const
- MINIMUM_DIST = 1;
- MAXIMUM_DIST = 4;
- var
- color: TIntegerArray;
- TPA: TPointArray;
- ATPA: T2DPointArray;
- i, j, bmp: Integer;
- begin
- ClearDebug;
- TPA := [Point(5, 5), Point(3, 4), Point(15, 15), Point(18, 16), Point(4, 5), Point(14, 18),
- Point(78, 68), Point(75, 72), Point(74, 74), Point(6, 6), Point(79, 70), Point(20, 19)];
- ATPA := TPAGroupEx(TPA, MINIMUM_DIST, MAXIMUM_DIST);
- WriteLn(ToStr(ATPA));
- color := [255, 16777215, 16711680, 65535, 32768, 8421504];
- bmp := CreateBitmap(100, 100);
- for i := 0 to High(ATPA) do
- for j := 0 to High(ATPA[i]) do
- FastSetPixel(bmp, ATPA[i][j].X, ATPA[i][j].Y, color[(i mod 6)]);
- DisplayDebugImgWindow(100, 100);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- end.[/simba]
- [/spoiler]
- [spoiler="TPAToParts"]
- [simba]type
- TPartitionMethod = (pm_PartSize, pm_PartAmount);
- {==============================================================================]
- Explanation: Breaks TPA to parts (TPA => ATPA). Contains 2 methods:
- -pm_PartSize (Breaks TPA to ATPA by size of the parts) [x = size]
- -pm_PartAmount (Breaks TPA to ATPA by amount of the parts) [x = amount]
- [==============================================================================}
- function TPAToParts(TPA: TPointArray; method: TPartitionMethod; x: Integer): T2DPointArray;
- var
- a, e, h, h2, i, i2, p, z, l: Integer;
- f: Boolean;
- begin
- h := High(TPA);
- if ((h > -1) and (x > 0)) then
- begin
- case method of
- pm_PartSize:
- if (x <= h) then
- begin
- Inc(h);
- p := (h div x);
- if ((p * x) < h) then
- Inc(p);
- SetLength(Result, p);
- for i := 0 to (p - 1) do
- for i2 := 0 to (x - 1) do
- begin
- SetLength(Result[i], x);
- if (a < h) then
- begin
- Result[i][i2] := TPoint(TPA[a]);
- Inc(a);
- end else
- begin
- SetLength(Result[i], i2);
- Exit;
- end;
- end;
- end else
- f := True;
- pm_PartAmount:
- if (h > -1) then
- begin
- if (h < (x - 1)) then
- x := (h + 1);
- p := Floor((h + 1) / x);
- if (p = 0) then
- p := 1;
- e := ((h + 1) - (p * x));
- if (e >= (h + 1)) then
- e := 0;
- SetLength(Result, x);
- for i := 0 to (x - 1) do
- begin
- if ((e >= (i + 1)) and (e > 0)) then
- SetLength(Result[i], (p + 1))
- else
- if (i <= h) then
- SetLength(Result[i], p);
- h2 := High(Result[i]);
- for i2 := 0 to h2 do
- begin
- Result[i][i2] := TPoint(TPA[a]);
- Inc(a);
- end;
- end;
- end else
- f := True;
- end;
- if f then
- begin
- SetLength(Result, 1);
- l := Length(TPA);
- SetLength(Result[0], l);
- for z := 0 to (l - 1) do
- Result[0][z] := TPoint(TPA[z]);
- end;
- end else
- SetLength(Result, 0);
- end;
- var
- TPA: TPointArray;
- begin
- ClearDebug;
- TPA := [Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9),
- Point(0, 1), Point(2, 3), Point(4, 5), Point(6, 7), Point(8, 9)];
- WriteLn('TPAToParts(TPA, pm_PartAmount, 3): ' + ToStr(TPAToParts(TPA, pm_PartAmount, 3)));
- WriteLn('TPAToParts(TPA, pm_PartSize, 3): ' + ToStr(TPAToParts(TPA, pm_PartSize, 3)));
- end.[/simba]
- [/spoiler]
- [spoiler="ATPAMerge"]
- [simba]{==============================================================================]
- Explanation: Merges T2DPointArray (ATPA) to TPointArray.
- [==============================================================================}
- function ATPAMerge(ATPA: T2DPointArray): TPointArray;
- var
- i, i2, h, h2, r: Integer;
- begin
- h := High(ATPA);
- if (h > -1) then
- begin
- for i := 0 to h do
- IncEx(r, (High(ATPA[i]) + 1));
- SetLength(Result, r);
- r := 0;
- for i := 0 to h do
- begin
- h2 := High(ATPA[i]);
- for i2 := 0 to h2 do
- begin
- Result[r] := TPoint(ATPA[i][i2]);
- Inc(r);
- end;
- end;
- end else
- SetLength(Result, 0);
- end;
- var
- ATPA: T2DPointArray;
- begin
- SetLength(ATPA, 3);
- ATPA[0] := [Point(0, 1), Point(2, 3)];
- ATPA[1] := [Point(4, 5)];
- ATPA[2] := [Point(6, 7), Point(8, 9)];
- WriteLn(ToStr(ATPAMerge(ATPA)));
- end.[/simba]
- [/spoiler]
- [spoiler="ATPAEmpty"]
- [simba]{==============================================================================]
- Explanation: Returns true if ATPA does not contain any points in it.
- [==============================================================================}
- function ATPAEmpty(ATPA: T2DPointArray): Boolean;
- var
- a, b: Integer;
- begin
- b := High(ATPA);
- for a := 0 to b do
- if (Length(ATPA[a]) > 0) then
- Break;
- Result := (a > b);
- end;
- var
- ATPA: T2DPointArray;
- begin
- ClearDebug;
- if ATPAEmpty(ATPA) then
- WriteLn('As you can see, ATPA does NOT contain any points in it.');
- SetLength(ATPA, 100);
- if ATPAEmpty(ATPA) then
- WriteLn('As you can see, ATPA STILL does NOT contain any points in it...');
- ATPA[75] := [Point(0, 0)];
- if not ATPAEmpty(ATPA) then
- WriteLn('We can finally find a point now!');
- end.[/simba]
- [/spoiler]
- [spoiler="ATPASize"]
- [simba]{==============================================================================]
- Explanation: Returns total amount of points that ATPA contains in it.
- [==============================================================================}
- function ATPASize(ATPA: T2DPointArray): Integer;
- var
- a, b: Integer;
- begin
- Result := 0;
- b := High(ATPA);
- for a := 0 to b do
- Result := (Result + Length(ATPA[a]));
- end;
- var
- ATPA: T2DPointArray;
- begin
- ClearDebug;
- WriteLn('1. ATPASize(ATPA): ' + IntToStr(ATPASize(ATPA)));
- SetLength(ATPA, 100);
- WriteLn('2. ATPASize(ATPA): ' + IntToStr(ATPASize(ATPA)));
- ATPA[75] := [Point(0, 0)];
- WriteLn('3. ATPASize(ATPA): ' + IntToStr(ATPASize(ATPA)));
- ATPA[38] := [Point(1, 2), Point(3, 4)];
- WriteLn('4. ATPASize(ATPA): ' + IntToStr(ATPASize(ATPA)));
- end.[/simba]
- [/spoiler]
- [spoiler="ATPAClean"]
- [simba]{==============================================================================]
- Explanation: Removes all the empty indexes from ATPA.
- [==============================================================================}
- procedure ATPAClean(var ATPA: T2DPointArray);
- var
- a, b, c: Integer;
- begin
- b := High(ATPA);
- for a := 0 to b do
- if (Length(ATPA[a]) > 0) then
- begin
- ATPA[c] := ATPA[a];
- Inc(c);
- end;
- SetLength(ATPA, c);
- end;
- var
- ATPA: T2DPointArray;
- begin
- ClearDebug;
- SetLength(ATPA, 100);
- ATPAClean(ATPA);
- WriteLn('ATPA: ' + ToStr(ATPA));
- SetLength(ATPA, 100);
- ATPA[55] := [Point(0, 1), Point(2, 3)];
- ATPAClean(ATPA);
- WriteLn('ATPA: ' + ToStr(ATPA));
- SetLength(ATPA, 100);
- ATPA[74] := [Point(6, 7), Point(8, 9)];
- ATPA[6] := [Point(4, 5)];
- ATPAClean(ATPA);
- WriteLn('ATPA: ' + ToStr(ATPA));
- end.[/simba]
- [/spoiler]
- [spoiler="ATPABounds"]
- [simba]{==============================================================================]
- Explanation: Returns the bounds of ATPA as TBox.
- [==============================================================================}
- function ATPABounds(ATPA: T2DPointArray): TBox;
- var
- a, b, x, y: Integer;
- s: Boolean;
- begin
- b := High(ATPA);
- if (b > -1) then
- begin
- for a := 0 to b do
- begin
- y := High(ATPA[a]);
- for x := 0 to y do
- if s then
- begin
- if (ATPA[a][x].X < Result.X1) then
- Result.X1 := ATPA[a][x].X
- else
- if (ATPA[a][x].X > Result.X2) then
- Result.X2 := ATPA[a][x].X;
- if (ATPA[a][x].Y < Result.Y1) then
- Result.Y1 := ATPA[a][x].Y
- else
- if (ATPA[a][x].Y > Result.Y2) then
- Result.Y2 := ATPA[a][x].Y;
- end else
- begin
- Result := IntToBox(ATPA[a][x].X, ATPA[a][x].Y, ATPA[a][x].X, ATPA[a][x].Y);
- s := True;
- end;
- end;
- end else
- Result := IntToBox(0, 0, 0, 0);
- end;
- var
- ATPA: T2DPointArray;
- begin
- SetLength(ATPA, 1000);
- ATPA[628] := [Point(102, 40), Point(89, 105)];
- ATPA[750] := [Point(55, 5)];
- ATPA[58] := [Point(5, 69), Point(105, 99), Point(10, 10)];
- WriteLn(ToStr(ATPABounds(ATPA)));
- end.[/simba]
- [/spoiler]
- [spoiler="ATPAAllBounds"]
- [simba]{==============================================================================]
- Explanation: Returns the bounds of ALL ATPA indexes as TBoxArray.
- [==============================================================================}
- function ATPAAllBounds(ATPA: T2DPointArray): TBoxArray;
- var
- a, b, x, y: Integer;
- s: Boolean;
- begin
- b := High(ATPA);
- SetLength(Result, (b + 1));
- for a := 0 to b do
- begin
- y := High(ATPA[a]);
- if (y > -1) then
- begin
- Result[a] := IntToBox(ATPA[a][0].X, ATPA[a][0].Y, ATPA[a][0].X, ATPA[a][0].Y);
- if (y > 0) then
- for x := 1 to y do
- begin
- if (ATPA[a][x].X < Result[a].X1) then
- Result[a].X1 := ATPA[a][x].X
- else
- if (ATPA[a][x].X > Result[a].X2) then
- Result[a].X2 := ATPA[a][x].X;
- if (ATPA[a][x].Y < Result[a].Y1) then
- Result[a].Y1 := ATPA[a][x].Y
- else
- if (ATPA[a][x].Y > Result[a].Y2) then
- Result[a].Y2 := ATPA[a][x].Y;
- end;
- end else
- Result[a] := IntToBox(0, 0, 0, 0);
- end;
- end;
- var
- ATPA: T2DPointArray;
- begin
- SetLength(ATPA, 10);
- ATPA[5] := [Point(102, 40), Point(89, 105)];
- ATPA[8] := [Point(55, 5)];
- ATPA[3] := [Point(5, 69), Point(105, 99), Point(10, 10)];
- WriteLn(ToStr(ATPAAllBounds(ATPA)));
- end.[/simba]
- [/spoiler]
- Going to add more stuff soon. :stirthepot:
- ..oh and, as always:
- Feel free to use/take/improve/anything - it's all open-source!
- Giving credit is always appreciated, but not really necessary for me. :)
- Have fun!
- -Jani
Advertisement
Add Comment
Please, Sign In to add comment