Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: DXF Translator
4 : * Purpose: Implements the OCS to WCS transformer used in DXF files.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
9 : * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
10 : * Copyright (c) 2018, Alan Thomas <alant@outlook.com.au>
11 : *
12 : * SPDX-License-Identifier: MIT
13 : ****************************************************************************/
14 :
15 : #include "ogr_dxf.h"
16 :
17 0 : OGRCoordinateTransformation *OGRDXFInsertTransformer::Clone() const
18 : {
19 0 : return new OGRDXFInsertTransformer(*this);
20 : }
21 :
22 : /************************************************************************/
23 : /* Mathematical helpers */
24 : /************************************************************************/
25 :
26 63 : static double Det2x2(double a, double b, double c, double d)
27 : {
28 63 : return a * d - b * c;
29 : }
30 :
31 7590 : static void CrossProduct(const double *a, const double *b, double *vResult)
32 : {
33 7590 : vResult[0] = a[1] * b[2] - a[2] * b[1];
34 7590 : vResult[1] = a[2] * b[0] - a[0] * b[2];
35 7590 : vResult[2] = a[0] * b[1] - a[1] * b[0];
36 7590 : }
37 :
38 11385 : static void Scale2Unit(double *adfV)
39 : {
40 : double dfLen =
41 11385 : sqrt(adfV[0] * adfV[0] + adfV[1] * adfV[1] + adfV[2] * adfV[2]);
42 11385 : if (dfLen != 0)
43 : {
44 11385 : adfV[0] /= dfLen;
45 11385 : adfV[1] /= dfLen;
46 11385 : adfV[2] /= dfLen;
47 : }
48 11385 : }
49 :
50 : /************************************************************************/
51 : /* OGRDXFOCSTransformer() */
52 : /************************************************************************/
53 :
54 3795 : OGRDXFOCSTransformer::OGRDXFOCSTransformer(double adfNIn[3],
55 3795 : bool bInverse /* = false */)
56 79695 : : aadfInverse()
57 : {
58 : static const double dSmall = 1.0 / 64.0;
59 : static const double adfWZ[3] = {0.0, 0.0, 1.0};
60 : static const double adfWY[3] = {0.0, 1.0, 0.0};
61 :
62 3795 : dfDeterminant = 0.0;
63 3795 : Scale2Unit(adfNIn);
64 3795 : memcpy(adfN, adfNIn, sizeof(double) * 3);
65 :
66 3795 : if ((std::abs(adfN[0]) < dSmall) && (std::abs(adfN[1]) < dSmall))
67 3732 : CrossProduct(adfWY, adfN, adfAX);
68 : else
69 63 : CrossProduct(adfWZ, adfN, adfAX);
70 :
71 3795 : Scale2Unit(adfAX);
72 3795 : CrossProduct(adfN, adfAX, adfAY);
73 3795 : Scale2Unit(adfAY);
74 :
75 3795 : if (bInverse == true)
76 : {
77 7 : const double a[4] = {0.0, adfAX[0], adfAY[0], adfN[0]};
78 7 : const double b[4] = {0.0, adfAX[1], adfAY[1], adfN[1]};
79 7 : const double c[4] = {0.0, adfAX[2], adfAY[2], adfN[2]};
80 :
81 7 : dfDeterminant = a[1] * b[2] * c[3] - a[1] * b[3] * c[2] +
82 7 : a[2] * b[3] * c[1] - a[2] * b[1] * c[3] +
83 7 : a[3] * b[1] * c[2] - a[3] * b[2] * c[1];
84 :
85 7 : if (dfDeterminant != 0.0)
86 : {
87 7 : const double k = 1.0 / dfDeterminant;
88 7 : const double a11 = adfAX[0];
89 7 : const double a12 = adfAY[0];
90 7 : const double a13 = adfN[0];
91 7 : const double a21 = adfAX[1];
92 7 : const double a22 = adfAY[1];
93 7 : const double a23 = adfN[1];
94 7 : const double a31 = adfAX[2];
95 7 : const double a32 = adfAY[2];
96 7 : const double a33 = adfN[2];
97 :
98 7 : aadfInverse[1][1] = k * Det2x2(a22, a23, a32, a33);
99 7 : aadfInverse[1][2] = k * Det2x2(a13, a12, a33, a32);
100 7 : aadfInverse[1][3] = k * Det2x2(a12, a13, a22, a23);
101 :
102 7 : aadfInverse[2][1] = k * Det2x2(a23, a21, a33, a31);
103 7 : aadfInverse[2][2] = k * Det2x2(a11, a13, a31, a33);
104 7 : aadfInverse[2][3] = k * Det2x2(a13, a11, a23, a21);
105 :
106 7 : aadfInverse[3][1] = k * Det2x2(a21, a22, a31, a32);
107 7 : aadfInverse[3][2] = k * Det2x2(a12, a11, a32, a31);
108 7 : aadfInverse[3][3] = k * Det2x2(a11, a12, a21, a22);
109 : }
110 : }
111 3795 : }
112 :
113 : /************************************************************************/
114 : /* Transform() */
115 : /************************************************************************/
116 :
117 3822 : int OGRDXFOCSTransformer::Transform(size_t nCount, double *adfX, double *adfY,
118 : double *adfZ, double * /* adfT */,
119 : int *pabSuccess /* = nullptr */)
120 : {
121 20252 : for (size_t i = 0; i < nCount; i++)
122 : {
123 16430 : const double x = adfX[i];
124 16430 : const double y = adfY[i];
125 16430 : const double z = adfZ[i];
126 :
127 16430 : adfX[i] = x * adfAX[0] + y * adfAY[0] + z * adfN[0];
128 16430 : adfY[i] = x * adfAX[1] + y * adfAY[1] + z * adfN[1];
129 16430 : adfZ[i] = x * adfAX[2] + y * adfAY[2] + z * adfN[2];
130 :
131 16430 : if (pabSuccess)
132 16430 : pabSuccess[i] = TRUE;
133 : }
134 3822 : return TRUE;
135 : }
136 :
137 : /************************************************************************/
138 : /* InverseTransform() */
139 : /************************************************************************/
140 :
141 14 : int OGRDXFOCSTransformer::InverseTransform(size_t nCount, double *adfX,
142 : double *adfY, double *adfZ)
143 : {
144 14 : if (dfDeterminant == 0.0)
145 0 : return FALSE;
146 :
147 28 : for (size_t i = 0; i < nCount; i++)
148 : {
149 14 : const double x = adfX[i];
150 14 : const double y = adfY[i];
151 14 : const double z = adfZ[i];
152 :
153 14 : adfX[i] = x * aadfInverse[1][1] + y * aadfInverse[1][2] +
154 14 : z * aadfInverse[1][3];
155 14 : adfY[i] = x * aadfInverse[2][1] + y * aadfInverse[2][2] +
156 14 : z * aadfInverse[2][3];
157 14 : adfZ[i] = x * aadfInverse[3][1] + y * aadfInverse[3][2] +
158 14 : z * aadfInverse[3][3];
159 : }
160 14 : return TRUE;
161 : }
162 :
163 : /************************************************************************/
164 : /* ComposeOnto() */
165 : /* */
166 : /* Applies this transformer to the given affine transformer. */
167 : /************************************************************************/
168 :
169 3 : void OGRDXFOCSTransformer::ComposeOnto(OGRDXFAffineTransform &oCT) const
170 : {
171 : double adfNew[12];
172 :
173 3 : adfNew[0] = adfAX[0] * oCT.adfData[0] + adfAY[0] * oCT.adfData[1] +
174 3 : adfN[0] * oCT.adfData[2];
175 3 : adfNew[1] = adfAX[1] * oCT.adfData[0] + adfAY[1] * oCT.adfData[1] +
176 3 : adfN[1] * oCT.adfData[2];
177 3 : adfNew[2] = adfAX[2] * oCT.adfData[0] + adfAY[2] * oCT.adfData[1] +
178 3 : adfN[2] * oCT.adfData[2];
179 :
180 3 : adfNew[3] = adfAX[0] * oCT.adfData[3] + adfAY[0] * oCT.adfData[4] +
181 3 : adfN[0] * oCT.adfData[5];
182 3 : adfNew[4] = adfAX[1] * oCT.adfData[3] + adfAY[1] * oCT.adfData[4] +
183 3 : adfN[1] * oCT.adfData[5];
184 3 : adfNew[5] = adfAX[2] * oCT.adfData[3] + adfAY[2] * oCT.adfData[4] +
185 3 : adfN[2] * oCT.adfData[5];
186 :
187 3 : adfNew[6] = adfAX[0] * oCT.adfData[6] + adfAY[0] * oCT.adfData[7] +
188 3 : adfN[0] * oCT.adfData[8];
189 3 : adfNew[7] = adfAX[1] * oCT.adfData[6] + adfAY[1] * oCT.adfData[7] +
190 3 : adfN[1] * oCT.adfData[8];
191 3 : adfNew[8] = adfAX[2] * oCT.adfData[6] + adfAY[2] * oCT.adfData[7] +
192 3 : adfN[2] * oCT.adfData[8];
193 :
194 3 : adfNew[9] = adfAX[0] * oCT.adfData[9] + adfAY[0] * oCT.adfData[10] +
195 3 : adfN[0] * oCT.adfData[11];
196 3 : adfNew[10] = adfAX[1] * oCT.adfData[9] + adfAY[1] * oCT.adfData[10] +
197 3 : adfN[1] * oCT.adfData[11];
198 3 : adfNew[11] = adfAX[2] * oCT.adfData[9] + adfAY[2] * oCT.adfData[10] +
199 3 : adfN[2] * oCT.adfData[11];
200 :
201 3 : memcpy(oCT.adfData, adfNew, sizeof(adfNew));
202 3 : }
|