mirror of
https://github.com/moparisthebest/Simba
synced 2024-11-30 12:52:16 -05:00
318 lines
7.6 KiB
ReStructuredText
318 lines
7.6 KiB
ReStructuredText
.. _scriptref-dtm:
|
|
|
|
Deformable Template Models (DTM)
|
|
================================
|
|
|
|
A DTM is in my view just a relatively simple way of defining a relationship
|
|
between several points. Each of these points have a relative offset to each
|
|
other, and may different in colour, tolerance, area size and shape.
|
|
A DTM generally consists out of one *Main Point*, and several
|
|
*Sub Points*.
|
|
|
|
Finding functions for DTM include the usual parameters. For explanation on
|
|
these, see :ref:`scriptref-finding`.
|
|
|
|
The structure of a DTM looks like this:
|
|
|
|
|
|
.. figure:: ../../Pics/DTM.png
|
|
:scale: 100 %
|
|
:alt: Structure of a DTM
|
|
|
|
Where each point in a DTM has a colour, tolerance, area size and area shape
|
|
entity. The main point's *point* is typically ``(0, 0)``, and all the
|
|
*subpoint* points are relative to the main point.
|
|
|
|
Example of a simple DTM
|
|
-----------------------
|
|
|
|
If one was to create his own DTM, he would first have to think of a useful DTM
|
|
structure.
|
|
|
|
Say:
|
|
|
|
.. code-block:: pascal
|
|
|
|
MainPoint = (123, 456)
|
|
SubPoint_1 = (122, 460)
|
|
SubPoint_2 = (120, 450)
|
|
|
|
Then we could create the following MDTM structure:
|
|
|
|
.. code-block:: pascal
|
|
|
|
// Give dtm.p a length of three.
|
|
// Mainpoint
|
|
dtm.p[0] = Point(123, 456);
|
|
|
|
// Subpoints
|
|
dtm.p[1] = Point(122, 460)
|
|
dtm.p[2] = Point(120, 450)
|
|
|
|
Note that we do not include other variables, such as colour, tolerance, area
|
|
size and area shape; they are of no importance in this example.
|
|
|
|
However, this code is not very clear about the DTM's points.
|
|
Better would be to write:
|
|
|
|
.. code-block:: pascal
|
|
|
|
// Give dtm.p a length of three.
|
|
// Mainpoint
|
|
dtm.p[0] = Point(0, 0);
|
|
|
|
// Subpoints
|
|
dtm.p[1] = Point(-1, 4) // 122 - 123 = -1, 460 - 456 = 4
|
|
dtm.p[2] = Point(-3, -6) // 120 - 123 = -3, 450 - 456 = -6
|
|
|
|
As you can see it is perfectly valid to use negative points.
|
|
|
|
Colour and Tolerance
|
|
--------------------
|
|
|
|
The colour value of a point in a DTM is just a RGB integer value.
|
|
Black = 0, Red = 255, White = 16777215, et cetera.
|
|
|
|
The value tolerance decides if a colour is similar enough to the given
|
|
colour; if this is the case, we say that the colours *matched*.
|
|
|
|
With no Area Size and Area Shape specified
|
|
we say that a DTM matches if for each
|
|
point in the DTM, the colour at the relative point matches the colour in dtm
|
|
with the given tolerance.
|
|
|
|
.. Colour and Tolerance
|
|
.. --------------------
|
|
|
|
.. \forall p \in P, \forall t \in Tol, \forall c \in Col : T(C(p), c) \leq t
|
|
|
|
.. With C() defining the colour at the given point, and T() defining the tolerance
|
|
.. between the two given colours.
|
|
|
|
Area Size and Shape
|
|
-------------------
|
|
|
|
Area Size and Shape add that nifty extra functionality to DTM's.
|
|
*Area Size* defines the area that should all match the colour
|
|
with the given tolerance.
|
|
*Area Shape* is currently not implemented, mainly because
|
|
we haven't found a good use for area shapes.
|
|
|
|
Loading a DTM from a string
|
|
----------------------------
|
|
|
|
It is also possible to load a DTM from a *zipped* string.
|
|
The details of the algorithm will not be explained here. (Have a look at dtm.pas
|
|
if you're interested)
|
|
|
|
MDTM and TDTM
|
|
-------------
|
|
|
|
One may know DTM's as a different type:
|
|
|
|
.. code-block:: pascal
|
|
|
|
TDTMPointDef = record
|
|
x, y, Color, Tolerance, AreaSize, AreaShape: integer;
|
|
end;
|
|
|
|
TDTMPointDefArray = Array Of TDTMPointDef;
|
|
|
|
TDTM = record
|
|
MainPoint: TDTMPointDef;
|
|
SubPoints: TDTMPointDefArray;
|
|
end;
|
|
|
|
The MML provides the two functions *MDTMtoTDTM* and *TDTMtoMDTM* to
|
|
directly convert between the two types.
|
|
|
|
Main Point and AreaSize / Shape
|
|
-------------------------------
|
|
|
|
The main point's area size and shape are not used in the current
|
|
implementation. It wouldn't be that hard to add them, however.
|
|
|
|
DTMFromString
|
|
-------------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function DTMFromString(const DTMString: String): Integer;
|
|
|
|
Load a DTM from a string generated by the DTM Editor.
|
|
|
|
SetDTMName
|
|
----------
|
|
|
|
.. code-block:: pascal
|
|
|
|
procedure SetDTMName(DTM : integer;const name : string);
|
|
|
|
|
|
Assign the DTM a name. Very useful for debugging purposes as it allows the
|
|
programmers to find out what DTMs are not being freed.
|
|
|
|
FreeDTM
|
|
-------
|
|
|
|
.. code-block:: pascal
|
|
|
|
procedure FreeDTM(DTM: Integer);
|
|
|
|
Free a DTM identified by *DTM*.
|
|
|
|
|
|
FindDTM
|
|
-------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function FindDTM(DTM: Integer; var x, y: Integer;
|
|
xs, ys, xe, ye: Integer): Boolean;
|
|
|
|
FindDTM is the most basic DTM finding function. It takes a box to search in,
|
|
defined by *x1, y1, x2, y2*; and if the DTM is found, it will set *x* and
|
|
*y* to the coordinate the DTM was found at and it will also return true.
|
|
Else, it returns false. Once a DTM is found, it will stop searching.
|
|
In other words; it always returns the first found DTM.
|
|
|
|
FindDTMs
|
|
--------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function FindDTMs(DTM: Integer; var p: TPointArray;
|
|
xs, ys, xe, ye: Integer): Boolean;
|
|
|
|
FindDTMs is like FindDTM, but it returns an array of
|
|
*x* and *y*, as the *TPointArray* type.
|
|
|
|
FindDTMRotatedSE
|
|
----------------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function FindDTMRotatedSE(DTM: Integer; var x, y: Integer;
|
|
xs, ys, xe, ye: Integer; sAngle, eAngle, aStep: Extended;
|
|
var aFound: Extended): Boolean;
|
|
|
|
FindDTMRotatedSE behaves like FindDTM. Only, it will rotate the DTM between
|
|
sAngle and eAngle by aStep each time. It will also return the angle which the
|
|
DTM was found at. Start rotating at StartAngle.
|
|
|
|
FindDTMRotatedAlternating
|
|
-------------------------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function FindDTMRotatedAlternating(DTM: Integer; var x, y: Integer;
|
|
xs, ys, xe, ye: Integer;
|
|
sAngle, eAngle, aStep: Extended; var aFound: Extended): Boolean;
|
|
|
|
FindDTMRotated behaves like FindDTM. Only, it will rotate the DTM between
|
|
sAngle and eAngle by aStep each time. It will also return the angle which the
|
|
DTM was found at. Starts at 0 degrees and alternatives between - and + aStep to search for the DTM.
|
|
|
|
|
|
FindDTMsRotatedSE
|
|
-----------------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function FindDTMsRotatedSE(DTM: Integer; var Points: TPointArray;
|
|
xs, ys, xe, ye: Integer; sAngle, eAngle, aStep: Extended;
|
|
var aFound: T2DExtendedArray) : Boolean;
|
|
|
|
FindDTMsRotatedSE behaves like FindRotatedDTMSE, but finds all DTM occurances.
|
|
Since one point can be found on several angles, aFound is a 2d array.
|
|
|
|
FindDTMsRotatedAlternating
|
|
--------------------------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function FindDTMsRotatedAlternating(DTM: Integer;
|
|
var Points: TPointArray; xs, ys, xe, ye: Integer; sAngle, eAngle, aStep:
|
|
Extended; var aFound: T2DExtendedArray) : Boolean;
|
|
|
|
FindDTMsRotatedAlternating behaves like FindRotatedDTMAlternating,
|
|
but finds all DTM occurances.
|
|
Since one point can be found on several angles, aFound is a 2d array.
|
|
|
|
AddMDTM
|
|
-------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function AddMDTM(const d: TMDTM): Integer;
|
|
|
|
|
|
AddDTM
|
|
------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function AddDTM(const d: TMDTM): Integer;
|
|
|
|
Load a TMDTM structure as DTM in Simba's system. (After it is loaded you can use
|
|
it in FindDTM, etc)
|
|
|
|
|
|
AddSDTM
|
|
-------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function AddSDTM(const d: TSDTM): Integer;
|
|
|
|
Load a TSDTM structure as DTM in Simba's system. (After it is loaded you can use
|
|
it in FindDTM, etc)
|
|
|
|
|
|
GetDTM
|
|
------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function GetDTM(index: Integer) : TMDTM
|
|
|
|
Returns the TMDTM of the given DTM index.
|
|
|
|
|
|
SDTMToMDTM
|
|
----------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function SDTMToMDTM(Const DTM: TSDTM): TMDTM;
|
|
|
|
Convert a SDTM to MDTM.
|
|
|
|
PrintDTM
|
|
--------
|
|
|
|
.. code-block:: pascal
|
|
|
|
procedure PrintDTM(const DTM : TMDTM);
|
|
|
|
Print the DTM contents.
|
|
|
|
MDTMToSDTM
|
|
----------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function MDTMToSDTM(Const DTM: TMDTM): TSDTM;
|
|
|
|
Convert a MDTM to SDTM.
|
|
|
|
CreateDTMPoint
|
|
--------------
|
|
|
|
.. code-block:: pascal
|
|
|
|
function CreateDTMPoint(x,y,c,t,asz : integer; bp : boolean) : TMDTMPoint;
|
|
|
|
|
|
Create a DTM point.
|