LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/dxf - ogrdxf_ocstransformer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 105 106 99.1 %
Date: 2024-05-04 12:52:34 Functions: 7 7 100.0 %

          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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : 
      31             : #include "ogr_dxf.h"
      32             : 
      33             : /************************************************************************/
      34             : /*                         Mathematical helpers                         */
      35             : /************************************************************************/
      36             : 
      37          63 : static double Det2x2(double a, double b, double c, double d)
      38             : {
      39          63 :     return a * d - b * c;
      40             : }
      41             : 
      42        3776 : static void CrossProduct(const double *a, const double *b, double *vResult)
      43             : {
      44        3776 :     vResult[0] = a[1] * b[2] - a[2] * b[1];
      45        3776 :     vResult[1] = a[2] * b[0] - a[0] * b[2];
      46        3776 :     vResult[2] = a[0] * b[1] - a[1] * b[0];
      47        3776 : }
      48             : 
      49        5664 : static void Scale2Unit(double *adfV)
      50             : {
      51             :     double dfLen =
      52        5664 :         sqrt(adfV[0] * adfV[0] + adfV[1] * adfV[1] + adfV[2] * adfV[2]);
      53        5664 :     if (dfLen != 0)
      54             :     {
      55        5664 :         adfV[0] /= dfLen;
      56        5664 :         adfV[1] /= dfLen;
      57        5664 :         adfV[2] /= dfLen;
      58             :     }
      59        5664 : }
      60             : 
      61             : /************************************************************************/
      62             : /*                        OGRDXFOCSTransformer()                        */
      63             : /************************************************************************/
      64             : 
      65        1888 : OGRDXFOCSTransformer::OGRDXFOCSTransformer(double adfNIn[3],
      66        1888 :                                            bool bInverse /* = false */)
      67       39648 :     : aadfInverse()
      68             : {
      69             :     static const double dSmall = 1.0 / 64.0;
      70             :     static const double adfWZ[3] = {0.0, 0.0, 1.0};
      71             :     static const double adfWY[3] = {0.0, 1.0, 0.0};
      72             : 
      73        1888 :     dfDeterminant = 0.0;
      74        1888 :     Scale2Unit(adfNIn);
      75        1888 :     memcpy(adfN, adfNIn, sizeof(double) * 3);
      76             : 
      77        1888 :     if ((std::abs(adfN[0]) < dSmall) && (std::abs(adfN[1]) < dSmall))
      78        1825 :         CrossProduct(adfWY, adfN, adfAX);
      79             :     else
      80          63 :         CrossProduct(adfWZ, adfN, adfAX);
      81             : 
      82        1888 :     Scale2Unit(adfAX);
      83        1888 :     CrossProduct(adfN, adfAX, adfAY);
      84        1888 :     Scale2Unit(adfAY);
      85             : 
      86        1888 :     if (bInverse == true)
      87             :     {
      88           7 :         const double a[4] = {0.0, adfAX[0], adfAY[0], adfN[0]};
      89           7 :         const double b[4] = {0.0, adfAX[1], adfAY[1], adfN[1]};
      90           7 :         const double c[4] = {0.0, adfAX[2], adfAY[2], adfN[2]};
      91             : 
      92           7 :         dfDeterminant = a[1] * b[2] * c[3] - a[1] * b[3] * c[2] +
      93           7 :                         a[2] * b[3] * c[1] - a[2] * b[1] * c[3] +
      94           7 :                         a[3] * b[1] * c[2] - a[3] * b[2] * c[1];
      95             : 
      96           7 :         if (dfDeterminant != 0.0)
      97             :         {
      98           7 :             const double k = 1.0 / dfDeterminant;
      99           7 :             const double a11 = adfAX[0];
     100           7 :             const double a12 = adfAY[0];
     101           7 :             const double a13 = adfN[0];
     102           7 :             const double a21 = adfAX[1];
     103           7 :             const double a22 = adfAY[1];
     104           7 :             const double a23 = adfN[1];
     105           7 :             const double a31 = adfAX[2];
     106           7 :             const double a32 = adfAY[2];
     107           7 :             const double a33 = adfN[2];
     108             : 
     109           7 :             aadfInverse[1][1] = k * Det2x2(a22, a23, a32, a33);
     110           7 :             aadfInverse[1][2] = k * Det2x2(a13, a12, a33, a32);
     111           7 :             aadfInverse[1][3] = k * Det2x2(a12, a13, a22, a23);
     112             : 
     113           7 :             aadfInverse[2][1] = k * Det2x2(a23, a21, a33, a31);
     114           7 :             aadfInverse[2][2] = k * Det2x2(a11, a13, a31, a33);
     115           7 :             aadfInverse[2][3] = k * Det2x2(a13, a11, a23, a21);
     116             : 
     117           7 :             aadfInverse[3][1] = k * Det2x2(a21, a22, a31, a32);
     118           7 :             aadfInverse[3][2] = k * Det2x2(a12, a11, a32, a31);
     119           7 :             aadfInverse[3][3] = k * Det2x2(a11, a12, a21, a22);
     120             :         }
     121             :     }
     122        1888 : }
     123             : 
     124             : /************************************************************************/
     125             : /*                            Transform()                               */
     126             : /************************************************************************/
     127             : 
     128        1915 : int OGRDXFOCSTransformer::Transform(size_t nCount, double *adfX, double *adfY,
     129             :                                     double *adfZ, double * /* adfT */,
     130             :                                     int *pabSuccess /* = nullptr */)
     131             : {
     132       13295 :     for (size_t i = 0; i < nCount; i++)
     133             :     {
     134       11380 :         const double x = adfX[i];
     135       11380 :         const double y = adfY[i];
     136       11380 :         const double z = adfZ[i];
     137             : 
     138       11380 :         adfX[i] = x * adfAX[0] + y * adfAY[0] + z * adfN[0];
     139       11380 :         adfY[i] = x * adfAX[1] + y * adfAY[1] + z * adfN[1];
     140       11380 :         adfZ[i] = x * adfAX[2] + y * adfAY[2] + z * adfN[2];
     141             : 
     142       11380 :         if (pabSuccess)
     143       11380 :             pabSuccess[i] = TRUE;
     144             :     }
     145        1915 :     return TRUE;
     146             : }
     147             : 
     148             : /************************************************************************/
     149             : /*                          InverseTransform()                          */
     150             : /************************************************************************/
     151             : 
     152          14 : int OGRDXFOCSTransformer::InverseTransform(size_t nCount, double *adfX,
     153             :                                            double *adfY, double *adfZ)
     154             : {
     155          14 :     if (dfDeterminant == 0.0)
     156           0 :         return FALSE;
     157             : 
     158          28 :     for (size_t i = 0; i < nCount; i++)
     159             :     {
     160          14 :         const double x = adfX[i];
     161          14 :         const double y = adfY[i];
     162          14 :         const double z = adfZ[i];
     163             : 
     164          14 :         adfX[i] = x * aadfInverse[1][1] + y * aadfInverse[1][2] +
     165          14 :                   z * aadfInverse[1][3];
     166          14 :         adfY[i] = x * aadfInverse[2][1] + y * aadfInverse[2][2] +
     167          14 :                   z * aadfInverse[2][3];
     168          14 :         adfZ[i] = x * aadfInverse[3][1] + y * aadfInverse[3][2] +
     169          14 :                   z * aadfInverse[3][3];
     170             :     }
     171          14 :     return TRUE;
     172             : }
     173             : 
     174             : /************************************************************************/
     175             : /*                             ComposeOnto()                            */
     176             : /*                                                                      */
     177             : /*    Applies this transformer to the given affine transformer.         */
     178             : /************************************************************************/
     179             : 
     180           3 : void OGRDXFOCSTransformer::ComposeOnto(OGRDXFAffineTransform &oCT) const
     181             : {
     182             :     double adfNew[12];
     183             : 
     184           3 :     adfNew[0] = adfAX[0] * oCT.adfData[0] + adfAY[0] * oCT.adfData[1] +
     185           3 :                 adfN[0] * oCT.adfData[2];
     186           3 :     adfNew[1] = adfAX[1] * oCT.adfData[0] + adfAY[1] * oCT.adfData[1] +
     187           3 :                 adfN[1] * oCT.adfData[2];
     188           3 :     adfNew[2] = adfAX[2] * oCT.adfData[0] + adfAY[2] * oCT.adfData[1] +
     189           3 :                 adfN[2] * oCT.adfData[2];
     190             : 
     191           3 :     adfNew[3] = adfAX[0] * oCT.adfData[3] + adfAY[0] * oCT.adfData[4] +
     192           3 :                 adfN[0] * oCT.adfData[5];
     193           3 :     adfNew[4] = adfAX[1] * oCT.adfData[3] + adfAY[1] * oCT.adfData[4] +
     194           3 :                 adfN[1] * oCT.adfData[5];
     195           3 :     adfNew[5] = adfAX[2] * oCT.adfData[3] + adfAY[2] * oCT.adfData[4] +
     196           3 :                 adfN[2] * oCT.adfData[5];
     197             : 
     198           3 :     adfNew[6] = adfAX[0] * oCT.adfData[6] + adfAY[0] * oCT.adfData[7] +
     199           3 :                 adfN[0] * oCT.adfData[8];
     200           3 :     adfNew[7] = adfAX[1] * oCT.adfData[6] + adfAY[1] * oCT.adfData[7] +
     201           3 :                 adfN[1] * oCT.adfData[8];
     202           3 :     adfNew[8] = adfAX[2] * oCT.adfData[6] + adfAY[2] * oCT.adfData[7] +
     203           3 :                 adfN[2] * oCT.adfData[8];
     204             : 
     205           3 :     adfNew[9] = adfAX[0] * oCT.adfData[9] + adfAY[0] * oCT.adfData[10] +
     206           3 :                 adfN[0] * oCT.adfData[11];
     207           3 :     adfNew[10] = adfAX[1] * oCT.adfData[9] + adfAY[1] * oCT.adfData[10] +
     208           3 :                  adfN[1] * oCT.adfData[11];
     209           3 :     adfNew[11] = adfAX[2] * oCT.adfData[9] + adfAY[2] * oCT.adfData[10] +
     210           3 :                  adfN[2] * oCT.adfData[11];
     211             : 
     212           3 :     memcpy(oCT.adfData, adfNew, sizeof(adfNew));
     213           3 : }

Generated by: LCOV version 1.14