1 /**************************************************************************** 2 * Copyright (C) 2008-2011 by Matteo Franchin * 3 * * 4 * This file is part of Box. * 5 * * 6 * Box is free software: you can redistribute it and/or modify it * 7 * under the terms of the GNU Lesser General Public License as published * 8 * by the Free Software Foundation, either version 3 of the License, or * 9 * (at your option) any later version. * 10 * * 11 * Box is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 * GNU Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with Box. If not, see <http://www.gnu.org/licenses/>. * 18 ****************************************************************************/ 19 20 21 #ifndef _BOX_LIBG_TRANSFORM_H 22 # define _BOX_LIBG_TRANSFORM_H 23 24 # include <box/types.h> 25 # include "graphic.h" 26 27 /** Flags used to specify which transformations are allowed. */ 28 typedef enum { 29 BOXGALLOW_TRANSLATE_X = 0x1, /**< Allow automatic translation along x */ 30 BOXGALLOW_TRANSLATE_Y = 0x2, /**< Allow automatic translation along y */ 31 BOXGALLOW_TRANSLATE = 0x3, /**< Allow automatic translation in x, y */ 32 BOXGALLOW_ROTATE = 0x4, /**< Allow automatic rotation */ 33 BOXGALLOW_SCALE = 0x8, /**< Allow automatic scaling */ 34 BOXGALLOW_ANISOTROPIC = 0x10, /**< Allow different scaling in x and y */ 35 BOXGALLOW_INVERT = 0x20, /**< Allow mirroring the figure */ 36 BOXGALLOW_DEFORM = 0x30, /**< Allow mirroring and anisotropic scaling */ 37 BOXGALLOW_ALL = 0x3f /**< All flags or-ed together */ 38 39 } BoxGAllow; 40 41 /** Structure containing a transformation in terms of translation vector, 42 * rotation center and angle and scaling factors. From this structure 43 * a transformation matrix can be obtained. 44 */ 45 typedef struct { 46 BoxPoint translation, 47 rotation_center; 48 BoxReal rotation_angle, 49 rotation_cos, 50 rotation_sin, 51 scale_factor, 52 scaling_angle, 53 scaling_cos, 54 scaling_sin; 55 56 } BoxGTransform; 57 58 /** Used by BoxG_Auto_Transform to signal errors. */ 59 typedef enum { 60 BOXGAUTOTRANSFORMERR_NO_ERR=0, 61 BOXGAUTOTRANSFORMERR_NOT_ENOUGH_POINTS, 62 BOXGAUTOTRANSFORMERR_ZERO_WEIGHTS, 63 BOXGAUTOTRANSFORMERR_NOT_IMPLEMENTED 64 65 } BoxGAutoTransformErr; 66 67 68 /** Provide a string representation of the given BoxGAutoTransformErr. */ 69 const char *BoxGAutoTransformErr_To_String(BoxGAutoTransformErr n); 70 71 /** From an initial transformation 'transform', 'n' constraints (provided in 72 * 'src', 'dst' and 'weight') and a set of allowed transformations, 73 * 'allowed_transformation', finds the one which best satisfies the 74 * constraints. In particular, the objective is to minimise the function: 75 * 76 * f(q) = sum_i {weight[i]*(T(q) src[i] - dst[i])^2} / sum_i {weight[i]} 77 * 78 * where T[q] is a transformation parametrized by q, which is a vector made 79 * by all the available degrees of freedom. The objective is then to determine 80 * 'q' and T(q). T(q) is then stored inside 'transform'. 81 */ 82 BoxGAutoTransformErr 83 BoxG_Auto_Transform(BoxGTransform *transform, 84 BoxPoint *src, BoxPoint *dst, BoxReal *weight, int n, 85 BoxGAllow allowed_transforms); 86 87 /** Convert a string to a BoxGAllow value to use with BoxG_Auto_Transform. This 88 * function allows quick specification of the allowed transformations. Allowed 89 * transformations are specified using letters. Each letter corresponds to an 90 * allowed transformation. For example: "rt" means that "r"otations and 91 * "t"ranslations are allowed. The order of letters does not matter, e.g. "rt" 92 * is equivalent to "tr". The following table collects the associations 93 * between letters and transformations: 94 * "t" -> translation, "r" -> rotation, "s" -> scale, 95 * "a" -> allows anisotropic scaling, "i" -> allows inversion (mirroring) It 96 * is also possible to use "tx" or "ty" to enable translation only along one of 97 * the axes. It is also possible to give sign "+" and "-". The sign change the 98 * behaviour of the function. "+" means that the following characters should be 99 * used to enable transformations (default), while "-" means that they should 100 * be used to disable transformations. This is handy for concatenated 101 * strings. Example: allowed + "-txr" means that we should do whathever 102 * specified by 'allowed', but we should not translate along-x nor rotate. 103 * There are then a few characters to fine tune the behaviour of the function. 104 * When 'string' starts with a white space " ", the flags are or-ed over the 105 * pre-existing flags in '*allow' (while if the string does not start with a 106 * space the initial value of '*allow' is ignored, i.e. set to zero). Spaces in 107 * the middle of the string are ignored. 108 */ 109 BoxTask BoxGAllow_Of_String(BoxGAllow *allow, const char *string); 110 111 #endif /*_BOX_LIBG_TRANSFORM_H */ 112