Jump to content
slacky

[Plugin] SCARExt - Collection of shit for SCAR

Recommended Posts

I made my self a small library, just to extend the functionality found in SCAR, I probably won't use this as much my self.. I just always need to have something to do... :-b

So it ended up here, as Janilabo kept telling me to put it on github.. In the end I did do that... And figured that I could just as well tell ya all about it!

 

Source: https://github.com/WarPie/SCARExt/

 

Download: SCARExt.rar (simply extract it in includes folder) (Last updated - 23. Oct 2013)

 

 

So the functions which are exported (:

 //** Math.pas **//
 function XT_DistManhattan(pt1,pt2: TPoint): Extended;
 function XT_DistEuclidean(pt1,pt2: TPoint): Extended;
 function XT_DistChebyshev(pt1,pt2: TPoint): Extended;
 function XT_DistOctagonal(pt1,pt2: TPoint): Extended;
 function XT_Modulo(X,Y:Extended): Extended;
 function XT_InCircle(const Pt, Center: TPoint; Radius: Integer): Boolean;
 function XT_InPoly(x,y:Integer; const Poly:TPointArray): Boolean;
 function XT_InPolyR(x,y:Integer; const Poly:TPointArray): Boolean;
 function XT_InPolyW(x,y:Integer; const Poly:TPointArray): Boolean;
 function XT_InEllipse(const Pt, Center:TPoint; YRad, XRad: Integer): Boolean;
 function XT_InRectange(Pt:TPoint; X1,Y1, X2,Y2: Integer): Boolean;

 //** Numeric.pas **//
 procedure XT_MinMaxTIA(const Arr: TIntArray; var Min:Integer; var Max: Integer);
 procedure XT_MinMaxTEA(const Arr: TExtArray; var Min:Extended; var Max: Extended);
 function XT_SumTIA(const Arr: TIntArray): Integer;
 function XT_SumTEA(const Arr: TExtArray): Extended;
 procedure XT_TIAsToTPA(const X:TIntArray; const Y:TIntArray; var TPA:TPointArray);
 function XTCore_TIAToATIA(const Arr:TIntArray; Width,Height:Integer): T2DIntArray;

 //** Finder.pas **//
 function XTCore_FindColorTolExLCH(const ImgArr:T2DIntArray; var TPA:TPointArray; Color, ColorTol, LightTol:Integer): Boolean;
 function XTCore_FindColorTolExLAB(const ImgArr:T2DIntArray; var TPA:TPointArray; Color, ColorTol, LightTol:Integer): Boolean;

 //** ContrastEdges.pas **//
 function XT_ContrastEdges(const ImgArr: T2DIntArray; MinDiff: Integer): TPointArray;
 function XT_ContrastEdgesGray(const ImgArr: T2DIntArray; MinDiff: Integer): TPointArray;

 //** DensityMap.pas **//
 function XT_DensityMap(const TPA:TPointArray; Radius, Passes:Integer): T2DExtArray;
 function XT_DensityMapNormed(const TPA:TPointArray; Radius, Passes, Beta:Integer): T2DIntArray;
 procedure XT_TPADensitySort(var Arr: TPointArray; Radius, Passes:Integer);

 //** Points.pas **//
 function XT_SumTPA(Arr: TPointArray): TPoint;
 procedure XT_TPASeparateAxis(const TPA: TPointArray; var X:TIntArray; var Y:TIntArray);
 procedure XT_TPAFilterBounds(var TPA: TPointArray; x1,y1,x2,y2:Integer);
 function XT_GetTPAExtremes(const TPA:TPointArray): TPointArray;
 function XT_GetTPABBox(const TPA:TPointArray): TPointArray;
 function XT_GetTPABoundingBox(const TPA:TPointArray): TPointArray;  //Alias for GetTPABBox;
 procedure XT_GetAdjacent(var adj:TPointArray; n:TPoint; EightWay:Boolean);
 procedure XT_ReverseTPA(var TPA: TPointArray);
 procedure XT_MoveTPA(var TPA: TPointArray; SX,SY:Integer);
 procedure XT_TPARemoveDupes(var TPA: TPointArray);
 procedure XT_LongestPolyVector(const Poly:TPointArray; var A,B:TPoint);
 function XT_InvertTPA(const TPA:TPointArray): TPointArray;
 function XT_RotateTPAEx(const TPA: TPointArray; const Center:TPoint; Radians: Extended): TPointArray;
 function XT_TPAPartition(const TPA:TPointArray; BoxWidth, BoxHeight:Integer): T2DPointArray;
 function XT_AlignTPA(TPA:TPointArray; Method: TAlignMethod; var Angle:Extended): TPointArray;
 function XT_CleanSortTPA(const TPA: TPointArray): TPointArray;
 function XT_UniteTPA(const TPA1, TPA2: TPointArray; RemoveDupes:Boolean): TPointArray;
 procedure XT_TPALine(var TPA:TPointArray; const P1:TPoint; const P2: TPoint);
 function XT_ConnectTPA(const TPA:TPointArray): TPointArray;
 function XT_ConnectTPAEx(TPA:TPointArray; Tension:Extended): TPointArray;
 function XT_XagonPoints(const Center:TPoint; Sides:Integer; const Dir:TPoint): TPointArray;
 procedure XT_TPAEllipse(var TPA:TPointArray; const Center: TPoint; RadX,RadY:Integer);
 procedure XT_TPACircle(var TPA:TPointArray; const Center: TPoint; Radius:Integer);
 procedure XT_TPASimplePoly(var TPA:TPointArray; const Center:TPoint; Sides:Integer; const Dir:TPoint);
 function XT_ConvexHull(const TPA:TPointArray): TPointArray;
 function XT_FloodFillTPAEx(const TPA:TPointArray; const Start:TPoint; EightWay, KeepEdges:Boolean): TPointArray;
 function XT_FloodFillTPA(const TPA:TPointArray; const Start:TPoint; EightWay:Boolean): TPointArray;
 function XT_TPAOutline(const TPA:TPointArray): TPointArray;
 function XT_TPABorder(const TPA:TPointArray): TPointArray;
 function XT_FloodFillPolygon(const Poly:TPointArray; EightWay:Boolean): TPointArray;
 function XT_ClusterTPAEx(const TPA: TPointArray; Distx,Disty: Integer; EightWay:Boolean): T2DPointArray;
 function XT_ClusterTPA(const TPA: TPointArray; Distance: Integer; EightWay:Boolean): T2DPointArray;
 function XT_TPASkeleton(const TPA:TPointArray; FMin,FMax:Integer): TPointArray;

 //** CSpline.pas and TPAExtShape.pas **//
 function XT_CSpline(const TPA:TPointArray; Tension:Extended; Connect:Boolean): TPointArray;
 function XT_TPAExtractShape(const PTS:TPointArray; Distance, EstimateRad:Integer): TPointArray;

 //** Collection.pas **//
 function XT_IntMatrix(W,H, Init:Integer): T2DIntArray;
 function XT_IntMatrixNil(W,H:Integer): T2DIntArray;
 procedure XT_IntMatrixSetPts(var Matrix:T2DIntArray; const Pts:TPointArray; Value:Integer; const Align:TPoint);
 function XT_BoolMatrix(W,H:Integer; Init:Boolean): T2DBoolArray;
 function XT_BoolMatrixNil(W,H:Integer): T2DBoolArray;
 procedure XT_BoolMatrixSetPts(var Matrix:T2DBoolArray; const Pts:TPointArray; Value:Boolean; const Align:TPoint);
 function XT_TPAToIntMatrix(const TPA:TPointArray; Init, Value:Integer; Align:Boolean): T2DIntArray;
 function XT_TPAToIntMatrixNil(const TPA:TPointArray; Value:Integer; Align:Boolean): T2DIntArray;
 function XT_TPAToBoolMatrix(const TPA:TPointArray; Init, Value:Boolean; Align:Boolean): T2DBoolArray;
 function XT_TPAToBoolMatrixNil(const TPA:TPointArray; Value:Boolean; Align:Boolean): T2DIntArray;
 procedure XT_BlurImageArr(var ImgArr:T2DIntArray; Radius:Integer);
 function XT_NormalizeATIA(const ATIA:T2DIntArray; Alpha, Beta:Integer): T2DIntArray;
 function XT_ATIAGetIndices(const ATIA:T2DIntArray; const Indices:TPointArray): TIntArray;

 //** Randomize.pas **//
 function XT_RandomTPA(Amount:Integer; MinX,MinY,MaxX,MaxY:Integer): TPointArray;
 function XT_RandomCenterTPA(Amount:Integer; CX,CY,RadX,RadY:Integer): TPointArray;

 

As you see... it's just a bunch of crap, some of this crap might just be useful! :-D

 

 

#-----------------------------------------------------------------------------------------

 

 

I'll walk trough a few of them functions which is worth noting..:

 

#XT_InPoly, XT_InPolyR, XT_InPolyW:

This are all methods of checking if a point is within a polygon (defined by a TPA).. I actually had to add three.. or I did not have to but I am cool like that!! =P

*XT_InPoly: The main version, it's a combination of Ray casting and Winding number algorithm.. Just to avoid "imperfect-polygons".. Costs more.. so if you are okay with a pretty precise "estimate" you can use:

*XT_InPolyR (RayCasting), or *XT_InPolyW (winding number)..

 

 

#XT_ClusterTPA(Ex)

ClusterTPA is a complex function, it's action is the same as SplitTPA(Ex) seen in Simba, and SCAR (Macro-programs), but unlike those, this one performance in O(n)-time, while SplitTPA(ex) has a time-complexity of O(n^2). My algorithm will on the other side abuse and maybe even rape your memory! :-D (joking...)

In short this algorithm uses a 2D-Matrix to cluster together the points that are within a given distance (Distx,Disty) from each other. It then returns 2D TPoint Array (T2DPointArray).

 

I honestly think that this function is very fast, can be used with LARGE sets of points, and relatively high distance..

A somewhat slower version can be found in the latest version of Simba, but that version is mostly created by Janilabo, partially extended on the grounds of my concept.

 

 

#XT_ContrastEdges(Gray)

Given a matrix that represents an image this algorithm extracts the contrast edge points.

The result is an Array of TPoint (TPointArray).

 

So you get the edges... :P

 

 

#XT_ConnectTPA

Quickly creates a line from from each point in the TPA (pts), to the next point. It uses XT_TPALine

 

 

#XT_ConvexHull

A 2D-implementation of ConvexHull. ConvexHull can be explained with simple words:

|> Given a Array of Points, imagine that you where to put a rubber band around am...

|> The points which strech the rubber band are the points returned by this algorithm.

 

Time complexity: O(mn) (M as in Width, and N as in Height) before sorting the points..

Once sorted and cleaned it's close to O(n).

 

Convex hull - Wikipedia, the free encyclopedia

 

Can be used together with InPoly(W/R), to check if points are within this shape...

 

#XT_TPAExtractShape

Similar to ConvexHull this also extracts the shape.. but it has rules! Three parameters are taken, only two of am which is actually important the TPA and `Distance`.. This is the maximum distance to it's net neighbors.. It's like a form for Alpha-Shape extraction (Concave Hull)... So it can actually extract the SHAPE.

Image to check out.. Middle shape = Convex, last shape = concave..: http://vis4.net/labs/wp/wp-content/uploads/2012/01/Bildschirmfoto-2012-01-03-um-01.18.09-380x217.png

 

This also returns the lines.. it's not optimal for usage with InPoly (it returns full lines connecting every points), can be changed on demand.

 

>> Visualization example (http://pastebin.com/raw.php?i=Wmsn4rzG)

 

 

#XT_TPADensitySort

TPADensitySort simply sorts your TPA by the point-clouds density.. So if a point is a "loner", it will end up at the end of the TPA, if points has many neighbors it has a high value..! =) So tightness = good! ;)

 

 

#XT_FloodFillPolygon

FloodFillPolygon is NOT the same as TPAFromPolygon found in SCAR >3.4!!!

This one is much cooler, and much faster! ;-D It does not give a crap about the polypoints within the outer polypoints (results in all the points on and within the edges of the polygon).. if that makes any sense. In other words it will fill the entire polygon defined by the outlines of the polygon, so even if the polygon crosses it self, or got holes, the holes will be filled, the "crossing it self"-part will be ignored.. So you always get a filled shape. Hence the name "FloodFill"

 

 

#XT_TPAPartition

Partitions a TPA, by splitting it in to boxes of `BoxWidth` and `BoxHeight`. The result is the ATPA containing all the area TPAs. So imagine the inventory, or bank-items in RS where each slot = one box, this functions creates/splits it up to those boxes..

 

 

#XT_TPABorder and XT_TPAOutline

TPABorder: Returns the border outside your shape.

TPAOutline: Returns the border on your shape.

For multiple shapes, I would suggest ClusterTPA(Dist = 1, 8way=False) first.. Then grab borders of the shapes you want.

 

 

#XT_TPASimplePoly

Uses `XagonPoints` combined with ConnectTPA to draw a line trough each

point given by `XagonPoints`. So we get a "proper polygon" with x sides. So it creates everything from triangles to over 100-sided polygons..

 

#-----------------------------------------------------------------------------------------

 

 

That's it for now.. source, and link to dll:

https://github.com/WarPie/SCARExt/

 

On a sidenote: The library also allows you to quickly create 2DBool- 2DIntArrays and (or as I call am matrices), this can be used for fast manipulation of TPoints, and for quick lookups. EG:

XT_TPAToBoolMatrix(TPA, False, True, True);

 

 

Examples are given up on request.

Edited by slacky
Link to comment
Share on other sites

Awesome work, slacky!

 

As you know, I have been waiting to see that GitHub repository for a while already... :D

Glad to see it is there now, BOOM!

 

I think you did excellent job with releasing this to public. Like, everything is nicely listed and also descriptions/examples of uses are available.. Brilliant presentation. :)

 

ME LIEK. Projects like this is just what SCAR community needs.

Link to comment
Share on other sites

Hehe! I bet u r happy now! :P But u know... I just had to reach about 50 functions before I could even consider to release it.. So it would not become a total flop like my old "SLACKLIB" :P

 

Anyways. thnk you for that positive comment! ;-)

Edited by slacky
Link to comment
Share on other sites

Hehe! I bet u r happy now! :P But u know... I just had to reach about 50 functions before I could even consider to release it.. So it would not become a total flop like my old "SLACKLIB" :P

 

Anyways. thnk you for that positive comment! ;-)

Ohhh definitely, I had to bug you about it for a while, haha!

..but it was definitely worth it, because now we can follow the progress of this plugin in the future easily. :P No more random uploading pages etc.

 

Hmm, something I noticed...

 

#XT_TPABorder and XT_TPAOutline
TPABorder: Returns the border outside your shape.

TPAOutline: Returns the border on your shape.

For multiple shapes, I would suggest ClusterTPA(Dist = 1, 8way=False) first.. Then grab borders of the shapes you want.

Wouldn't you need 8way=True instead for it?

Do enlighten me, if I am incorrect though..

Link to comment
Share on other sites

Ohhh definitely, I had to bug you about it for a while, haha!

..but it was definitely worth it, because now we can follow the progress of this plugin in the future easily. :P No more random uploading pages etc.

 

Hmm, something I noticed...

 

Wouldn't you need 8way=True instead for it?

Do enlighten me, if I am incorrect though..

Both works just fine, but yeah I guess 8way would in general be the better choice... I'm just trying to write comments on them functions quickly...

 

As a sidenote: TPABorder actually creates 8way floodfill ready points.. I made it that way so I could use it with FloodFillPolygon witout having to create a border of 2px (avoid having to iterate the outlines so many times..). It varies from 1-2px border depending on angle. Just give it a spin if you don't understand what I am saying (try it at EG: TPAFromCircle)..

Edited by slacky
Link to comment
Share on other sites

So I've added a simple plotting library mostly written in PascalScript. Nothing fancy in other words.

 

Example (be sure to download the latest SCARExt):

program New;
{$I SCARExt/SCARExt.scar}

var Plot: TPlot;
procedure ScriptTerminate;
begin 
 TPlotFree(Plot); 
end;

var j,t: Integer;
begin
 Plot := TPlotCreate(100,100, 8); //PlotW, PlotH, Font-size(test);

 (**** Configuration ****)
 Plot.Color := 255;
 Plot.LineColor := 127;
 Plot.DrawLine := True;
 TPlotSetAxisText(Plot, 'Over  Time (ms)', 'Random(-30,31)');
 TPlotSetBG(Plot, $DDDDDD, False);
 TPlotSetBG(Plot, $EFEFEF, True); 


 (**** Random plotting ****)
 WriteLn('Stop it with SCARs hotkey: Ctrl+Alt+S');

 t := GetSystemTime; 
 j := RandomRange(100,200);
 while True do 
 begin        
   TPlotClearRange(Plot, 1000,300, True); 
   j := RandomRange(j-30,j+31);
   TPlotAddPoints(Plot, [(GetSystemTime - t)], [j]);
   Wait(20); //Lets not have it going to fast..
 end;
end.

That code produces some live random plotting:

2f0ezyg.jpg

 

You are also free to change some of the colors (not all (yet?)) used to plot.. The size can be changed as well.

6y2zaq.jpg

 

 

More features will be added later..! And bugfixes where ever needed :-)

There are also enhancements in the latest SCARExt.. Among them you will see that ClusterTPA is much more stable speedwise, and is quite a bit faster.

 

Btw: I don't know if it might be useful, nor do I care! :-)

Edited by slacky
Link to comment
Share on other sites

Some new functions since I last wrote here... Among them you will find: Spline trough a set of points (XT_CSpline), Aligning TPA by longest side (XT_AlignTPA) with the X-axis, Finding the skeleton of a TPA (XT_TPASkeleton) and GetTPABBox.

 

XT_TPASkeleton(const TPA:TPointArray; FMin,FMax:Integer): TPointArray;

2565v1h.jpg

^ blueish pixels = skeleton.

- Fmin and FMax defaults at 2 and 6.. Image was produced with 4 and 5.

 

XT_AlignTPA(const TPA:TPointArray; Method: TAlignMethod; var Angle:Extended): TPointArray;

2ccl0yd.jpg

>> Gray pixels = Original TPA..

>> Black pixels = Aligned TPA...

 

- Method can be `AM_Extremes`, `AM_Convex` or `AM_BBox`. (Image was produced with AM_BBox).. BBox would probably produce the the best result.

- Angle returns how many degrees the TPA was rotated.

 

 

XT_GetTPABBox(const TPA:TPointArray): TPointArray;

mkdjjr.jpg

Returns the 4 points the defines the Min Bounding Rectangle.

Edited by slacky
Link to comment
Share on other sites

Been looking for a link to your OCR stuff can't seem to find any

Yeah. I never released a standalone SCAR version of the RS07 OCR engine (which I guess is what you want), I planned to, but I went inactive.

 

However the RS07 OCR engine is available in this RS07-extended version of SCARExt: http://slackworld.net/downloads/RML.rar

The one file you need is then the: SCARExt.dll (plugin).

 

To use the RS OCR you need the "RS_LoadFont" and "RS_FreeFont" found in OCR.scar

And the few functions here: https://github.com/WarPie/SCAR-RML/blob/master/Src/OCR.scar#L74

And so you also need the two "XT_Bmp2Matrix(...)" to convert the bmp to a matrix, and "XT_ClientBMP()" which grabs the client bitmap.

Edited by slacky
Link to comment
Share on other sites

Yeah. I never released a standalone SCAR version of the RS07 OCR engine (which I guess is what you want), I planned to, but I went inactive.

 

However the RS07 OCR engine is available in this RS07-extended version of SCARExt: http://slackworld.net/downloads/RML.rar

The one file you need is then the: SCARExt.dll (plugin).

 

To use the RS OCR you need the "RS_LoadFont" and "RS_FreeFont" found in OCR.scar

And the few functions here: https://github.com/WarPie/SCAR-RML/blob/master/Src/OCR.scar#L74

And so you also need the two "XT_Bmp2Matrix(...)" to convert the bmp to a matrix, and "XT_ClientBMP()" which grabs the client bitmap.

 

Well I got it working at least http://forums.scar-divi.com/showthread.php?t=2750&highlight=

https://github.com/OSI1/OfficialSCARInclude/commit/17a19959d01f333d25f98c2663327bbc3e268faf

 

What do you think of my implementation?

 

I have a couple of questions

 

1. Why all the XT_Chars?

2. What is StatChars2? Also you didn't use TradeChars?

3. Why have UpFont2/UpCharsShadow?

4. Interested about UpText's "more options" ******

5. What is \UpCharsShadow\Thumbs.db ?

Edited by Wanted
Link to comment
Share on other sites

Well I got it working at least http://forums.scar-divi.com/showthread.php?t=2750&highlight=

https://github.com/OSI1/OfficialSCARInclude/commit/17a19959d01f333d25f98c2663327bbc3e268faf

 

What do you think of my implementation?

 

I have a couple of questions

 

1. Why all the XT_Chars?

2. What is StatChars2? Also you didn't use TradeChars?

3. Why have UpFont2/UpCharsShadow?

4. Interested about UpText's "more options" ******

5. What is \UpCharsShadow\Thumbs.db ?

1. RS_*XT chars, and related OCR functions (IE: XT_GetTextAtEx) was an part of an attempt to have a faster alternative for the simple cases of OCR, IE for reading the login-text. SCARs OCR functions was to slow, and caused a notable delay whenever used, so I replaced it with my simpler method when I could.

2. I dont recall much regarding my RML. So I honestly do not know.

3: UpFont2 / UpCharsShadow -> Shadows are needed to get the uptext, without shadow fonts the engine is useless, and wont match anything. That's all I recall.

4: See below.

5: Just delete it or ignore it, it's just a Windows explorer ("thumbnail cache" file) that accidentally got added.

 

.....

The last parameter in RS_GetTextAtEx is used to speed up the process / just stops reading anything more when the given characters are matched. The "*" indicates that it can match any character(s).

 

RML is really just a big pile of mess as I was only using it as a way to pass some time, and have a simple lib to test out some SCARExt methods with.

 

 

Your implementation looks good.

Edited by slacky
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
  • Create New...