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