.. _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;


FindDTMs
--------

.. code-block:: pascal

    function FindDTMs(DTM: Integer; var p: TPointArray;
    xs, ys, xe, ye: Integer): Boolean;


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;


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;


FindDTMsRotatedSE
-----------------

.. code-block:: pascal

    function FindDTMsRotatedSE(DTM: Integer; var Points: TPointArray; 
    xs, ys, xe, ye: Integer; sAngle, eAngle, aStep: Extended;
    var aFound: T2DExtendedArray) : Boolean;


FindDTMsRotatedAlternating
--------------------------

.. code-block:: pascal

    function FindDTMsRotatedAlternating(DTM: Integer; 
    var Points: TPointArray; xs, ys, xe, ye: Integer; sAngle, eAngle, aStep: 
    Extended; var aFound: T2DExtendedArray) : Boolean;


AddMDTM
-------

.. code-block:: pascal

    function AddMDTM(const d: TMDTM): Integer;


AddDTM
------

.. code-block:: pascal

    function AddDTM(const d: TMDTM): Integer;


AddSDTM
-------

.. code-block:: pascal

    function AddSDTM(const d: TSDTM): Integer;


GetDTM
------

.. code-block:: pascal

    function GetDTM(index: Integer) : TMDTM


SDTMToMDTM
----------

.. code-block:: pascal

    function SDTMToMDTM(Const DTM: TSDTM): TMDTM;


PrintDTM
--------

.. code-block:: pascal

    procedure PrintDTM(const DTM : TMDTM);


MDTMToSDTM
----------

.. code-block:: pascal

    function MDTMToSDTM(Const DTM: TMDTM): TSDTM;


CreateDTMPoint
--------------

.. code-block:: pascal

    function CreateDTMPoint(x,y,c,t,asz : integer; bp : boolean) : TMDTMPoint;


