LCOV - code coverage report
Current view: top level - EnergyPlus - DXFEarClipping.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 74.6 % 244 182
Test Date: 2025-06-02 07:23:51 Functions: 62.5 % 8 5

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cmath>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array2D.hh>
      53              : #include <ObjexxFCL/Fmath.hh>
      54              : 
      55              : // EnergyPlus Headers
      56              : #include <EnergyPlus/DXFEarClipping.hh>
      57              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      58              : #include <EnergyPlus/DataSurfaces.hh>
      59              : #include <EnergyPlus/UtilityRoutines.hh>
      60              : 
      61              : namespace EnergyPlus {
      62              : 
      63              : namespace DXFEarClipping {
      64              : 
      65              :     // Module containing the routines dealing with triangulating a polygon of >4 sides
      66              : 
      67              :     // Module information:
      68              :     //       Author         Linda Lawrie
      69              :     //       Date written   October 2005
      70              : 
      71              :     // Purpose of this module:
      72              :     // This module provides the techniques and back up procedures for producing a triangulated
      73              :     // polygon from a >4 sided figure.  It is only used for DXF output.
      74              : 
      75              :     // Methodology employed:
      76              :     // Ear clipping has turned out to be the simplest, most robust technique.
      77              : 
      78            0 :     bool InPolygon(Vector const &point, Array1D<Vector> &poly, int const nsides)
      79              :     {
      80              :         // this routine is not used in the current scheme
      81              : 
      82              :         // Return value
      83              :         bool InPolygon;
      84              : 
      85              :         // Argument array dimensioning
      86            0 :         EP_SIZE_CHECK(poly, nsides);
      87              : 
      88              :         // Locals
      89              :         //'Return TRUE if the point (xp,yp) lies inside the circumcircle
      90              :         //'made up by points (x1,y1) (x2,y2) (x3,y3)
      91              :         //'The circumcircle centre is returned in (xc,yc) and the radius r
      92              :         //'NOTE: A point on the edge is inside the circumcircle
      93              : 
      94            0 :         Real64 constexpr epsilon(0.0000001);
      95              :         Real64 costheta;
      96              :         Real64 m1;
      97              :         Real64 m2;
      98              :         Real64 acosval;
      99              : 
     100              :         // Object Data
     101            0 :         Vector p1;
     102            0 :         Vector p2;
     103              : 
     104            0 :         InPolygon = false;
     105              : 
     106            0 :         Real64 anglesum = 0.0;
     107              : 
     108            0 :         for (int vert = 1; vert <= nsides - 1; ++vert) {
     109              : 
     110            0 :             p1.x = poly(vert).x - point.x;
     111            0 :             p1.y = poly(vert).y - point.y;
     112            0 :             p1.z = poly(vert).z - point.z;
     113              : 
     114            0 :             p2.x = poly(vert + 1).x - point.x;
     115            0 :             p2.y = poly(vert + 1).y - point.y;
     116            0 :             p2.z = poly(vert + 1).z - point.z;
     117              : 
     118            0 :             m1 = Modulus(p1);
     119            0 :             m2 = Modulus(p2);
     120              : 
     121            0 :             if (m1 * m2 <= epsilon) {
     122            0 :                 InPolygon = true;
     123            0 :                 break;
     124              :             } else {
     125            0 :                 costheta = (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z) / (m1 * m2);
     126            0 :                 acosval = std::acos(costheta);
     127            0 :                 anglesum += acosval;
     128              :             }
     129              :         }
     130              : 
     131            0 :         if (std::abs(anglesum - Constant::TwoPi) <= epsilon) {
     132            0 :             InPolygon = true;
     133              :         }
     134              : 
     135            0 :         return InPolygon;
     136            0 :     }
     137              : 
     138            0 :     Real64 Modulus(Vector const &point)
     139              :     {
     140              :         // this routine is not used in the current scheme
     141              : 
     142              :         // Return value
     143              :         Real64 rModulus;
     144              : 
     145            0 :         rModulus = std::sqrt(point.x * point.x + point.y * point.y + point.z * point.z);
     146              : 
     147            0 :         return rModulus;
     148              :     }
     149              : 
     150          142 :     int Triangulate(EnergyPlusData &state,
     151              :                     int const nsides, // number of sides to polygon
     152              :                     Array1D<Vector> &polygon,
     153              :                     Array1D<dTriangle> &outtriangles,
     154              :                     Real64 const surfazimuth,            // surface azimuth angle (outward facing normal)
     155              :                     Real64 const surftilt,               // surface tilt angle
     156              :                     std::string const &surfname,         // surface name (for error messages)
     157              :                     DataSurfaces::SurfaceClass surfclass // surface class
     158              :     )
     159              :     {
     160              : 
     161              :         // Subroutine information:
     162              :         //       Author         Linda Lawrie
     163              :         //       Date written   October 2005
     164              : 
     165              :         // Purpose of this subroutine:
     166              :         // This routine is a self-contained triangulation calculation from a polygon
     167              :         // of 3D vertices, nsides, to a returned set (as possible) of triangles -- noted
     168              :         // by vertex numbers.
     169              : 
     170              :         // Argument array dimensioning
     171          142 :         EP_SIZE_CHECK(polygon, nsides);
     172              : 
     173              :         // Subroutine parameter definitions:
     174          142 :         Real64 constexpr point_tolerance(0.00001);
     175              : 
     176              :         // Subroutine local variable declarations:
     177          142 :         Array1D_int ears(nsides);
     178          142 :         Array1D_int r_angles(nsides);
     179          142 :         Array1D<Real64> rangles(nsides);
     180          142 :         Array1D_int c_vertices(nsides);
     181          142 :         Array2D_int earvert(nsides, 3);
     182          142 :         Array1D_bool removed(nsides);
     183          142 :         Array1D_int earverts(3);
     184          142 :         Array1D<Real64> xvt(nsides);
     185          142 :         Array1D<Real64> yvt(nsides);
     186          142 :         Array1D<Real64> zvt(nsides);
     187              : 
     188              :         int nears;
     189              :         int nrangles;
     190              :         int ncverts;
     191              : 
     192              :         // Object Data
     193          142 :         Array1D<Vector_2d> vertex(nsides);
     194          142 :         Array1D<dTriangle> Triangle(nsides);
     195              : 
     196          142 :         if (surfclass == DataSurfaces::SurfaceClass::Floor || surfclass == DataSurfaces::SurfaceClass::Roof ||
     197              :             surfclass == DataSurfaces::SurfaceClass::Overhang) {
     198          142 :             CalcRfFlrCoordinateTransformation(nsides, polygon, surfazimuth, surftilt, xvt, yvt, zvt);
     199         1270 :             for (int svert = 1; svert <= nsides; ++svert) {
     200         5272 :                 for (int mvert = svert + 1; mvert <= nsides; ++mvert) {
     201         4144 :                     if (std::abs(xvt(svert) - xvt(mvert)) <= point_tolerance) {
     202          676 :                         xvt(svert) = xvt(mvert);
     203              :                     }
     204         4144 :                     if (std::abs(zvt(svert) - zvt(mvert)) <= point_tolerance) {
     205          816 :                         zvt(svert) = zvt(mvert);
     206              :                     }
     207              :                 }
     208              :             }
     209         1270 :             for (int svert = 1; svert <= nsides; ++svert) {
     210         1128 :                 vertex(svert).x = xvt(svert);
     211         1128 :                 vertex(svert).y = zvt(svert);
     212              :                 //      if (trackit) write(outputfiledebug,*) 'x=',xvt(svert),' y=',zvt(svert)
     213              :             }
     214          142 :         } else {
     215            0 :             CalcWallCoordinateTransformation(nsides, polygon, surfazimuth, surftilt, xvt, yvt, zvt);
     216            0 :             for (int svert = 1; svert <= nsides; ++svert) {
     217            0 :                 for (int mvert = svert + 1; mvert <= nsides; ++mvert) {
     218            0 :                     if (std::abs(xvt(svert) - xvt(mvert)) <= point_tolerance) {
     219            0 :                         xvt(svert) = xvt(mvert);
     220              :                     }
     221            0 :                     if (std::abs(zvt(svert) - zvt(mvert)) <= point_tolerance) {
     222            0 :                         zvt(svert) = zvt(mvert);
     223              :                     }
     224              :                 }
     225              :             }
     226            0 :             for (int svert = 1; svert <= nsides; ++svert) {
     227            0 :                 vertex(svert).x = xvt(svert);
     228            0 :                 vertex(svert).y = zvt(svert);
     229              :             }
     230              :         }
     231              : 
     232              :         // find ears
     233          142 :         int nvertcur = nsides;
     234          142 :         int ncount = 0;
     235          142 :         int svert = 1;
     236          142 :         int mvert = 2;
     237          142 :         int evert = 3;
     238          142 :         removed = false;
     239          843 :         while (nvertcur > 3) {
     240          702 :             generate_ears(state, nsides, vertex, ears, nears, r_angles, nrangles, c_vertices, ncverts, removed, earverts, rangles);
     241          702 :             if (!any_gt(ears, 0)) {
     242            2 :                 ShowWarningError(state,
     243            2 :                                  format("DXFOut: Could not triangulate surface=\"{}\", type=\"{}\", check surface vertex order(entry)",
     244              :                                         surfname,
     245            2 :                                         DataSurfaces::cSurfaceClass(surfclass)));
     246            1 :                 ++state.dataDXFEarClipping->errcount;
     247            1 :                 if (state.dataDXFEarClipping->errcount == 1 && !state.dataGlobal->DisplayExtraWarnings) {
     248            3 :                     ShowContinueError(state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on individual surfaces.");
     249              :                 }
     250            1 :                 if (state.dataGlobal->DisplayExtraWarnings) {
     251            0 :                     ShowMessage(state, format(" surface={} class={}", surfname, DataSurfaces::cSurfaceClass(surfclass)));
     252              : 
     253            0 :                     for (int j = 1; j <= nsides; ++j) {
     254            0 :                         ShowMessage(state, format(" side={} ({:.1R},{:.1R},{:.1R})", j, polygon(j).x, polygon(j).y, polygon(j).z));
     255              :                     }
     256            0 :                     ShowMessage(state, format(" number of triangles found={:12}", ncount));
     257            0 :                     for (int j = 1; j <= nrangles; ++j) {
     258            0 :                         ShowMessage(state, format(" r angle={} vert={} deg={:.1R}", j, r_angles(j), rangles(j) * Constant::RadToDeg));
     259              :                     }
     260              :                 }
     261            1 :                 break; // while loop
     262              :             }
     263          701 :             if (nears > 0) {
     264          701 :                 svert = earverts(1);
     265          701 :                 mvert = earverts(2);
     266          701 :                 evert = earverts(3);
     267              :                 // remove ear
     268          701 :                 ++ncount;
     269          701 :                 removed(mvert) = true;
     270          701 :                 earvert(ncount, 1) = svert;
     271          701 :                 earvert(ncount, 2) = mvert;
     272          701 :                 earvert(ncount, 3) = evert;
     273          701 :                 --nvertcur;
     274              :             }
     275          701 :             if (nvertcur == 3) {
     276          141 :                 int j = 1;
     277          141 :                 ++ncount;
     278         1261 :                 for (int i = 1; i <= nsides; ++i) {
     279         1120 :                     if (removed(i)) {
     280          697 :                         continue;
     281              :                     }
     282          423 :                     earvert(ncount, j) = i;
     283          423 :                     ++j;
     284              :                 }
     285              :             }
     286              :         }
     287              : 
     288          142 :         int ntri = ncount;
     289              : 
     290          984 :         for (int i = 1; i <= ntri; ++i) {
     291          842 :             Triangle(i).vv0 = earvert(i, 1);
     292          842 :             Triangle(i).vv1 = earvert(i, 2);
     293          842 :             Triangle(i).vv2 = earvert(i, 3);
     294              :         }
     295              : 
     296          142 :         outtriangles.allocate(ntri);
     297          984 :         for (int i = 1; i <= ntri; ++i) {
     298          842 :             outtriangles(i) = Triangle(i);
     299              :         }
     300              : 
     301          142 :         return ntri;
     302          142 :     }
     303              : 
     304         4420 :     Real64 angle_2dvector(Real64 const xa, // vertex coordinate
     305              :                           Real64 const ya, // vertex coordinate
     306              :                           Real64 const xb, // vertex coordinate
     307              :                           Real64 const yb, // vertex coordinate
     308              :                           Real64 const xc, // vertex coordinate
     309              :                           Real64 const yc  // vertex coordinate
     310              :     )
     311              :     {
     312              : 
     313              :         // Function information:
     314              :         //       Author         Linda Lawrie
     315              :         //       Date written   October 2005
     316              : 
     317              :         // Purpose of this function:
     318              :         // This function calculates the angle between two sides of a 2d polygon.
     319              :         // It computes the interior angle in radians at vertex
     320              :         // (XB,YB) of the chain formed by the directed edges from
     321              :         // (XA,YA) to (XB,YB) to (XC,YC).  The interior is to the
     322              :         // left of the two directed edges.
     323              : 
     324              :         // References:
     325              :         // Geometry Tools for Computer Graphics
     326              : 
     327              :         // Return value
     328              :         Real64 angle; // the angle, between 0 and 2*PI.
     329              : 
     330              :         // angle is set to PI/2 in the degenerate case.
     331              : 
     332              :         // Function parameter definitions:
     333         4420 :         Real64 constexpr epsilon(0.0000001);
     334              : 
     335         4420 :         Real64 x1 = xa - xb;
     336         4420 :         Real64 y1 = ya - yb;
     337         4420 :         Real64 x2 = xc - xb;
     338         4420 :         Real64 y2 = yc - yb;
     339              : 
     340         4420 :         Real64 t = std::sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2));
     341         4420 :         if (t == 0.0E+00) {
     342            0 :             t = 1.0E+00;
     343              :         }
     344              : 
     345         4420 :         t = (x1 * x2 + y1 * y2) / t;
     346              : 
     347         4420 :         if ((1.0E+00 - epsilon) < std::abs(t)) {
     348           81 :             t = sign(1.0E+00, t);
     349              :         }
     350              : 
     351         4420 :         angle = std::acos(t);
     352              : 
     353         4420 :         if (x2 * y1 - y2 * x1 < 0.0E+00) {
     354         1102 :             angle = 2.0E+00 * Constant::Pi - angle;
     355              :         }
     356              : 
     357         4420 :         return angle;
     358              :     }
     359              : 
     360        12980 :     bool polygon_contains_point_2d(int const nsides,            // number of sides (vertices)
     361              :                                    Array1D<Vector_2d> &polygon, // points of polygon
     362              :                                    Vector_2d const &point       // point to be tested
     363              :     )
     364              :     {
     365              : 
     366              :         // Function information:
     367              :         //       Author         Linda Lawrie
     368              :         //       Date written   October 2005
     369              : 
     370              :         // Purpose of this function:
     371              :         // Determine if a point is inside a simple 2d polygon.  For a simple polygon (one whose
     372              :         // boundary never crosses itself).  The polygon does not need to be convex.
     373              : 
     374              :         // References:
     375              :         // M Shimrat, Position of Point Relative to Polygon, ACM Algorithm 112,
     376              :         // Communications of the ACM, Volume 5, Number 8, page 434, August 1962.
     377              : 
     378              :         // Return value
     379              :         bool inside; // return value, true=inside, false = not inside
     380              : 
     381              :         // Argument array dimensioning
     382        12980 :         EP_SIZE_CHECK(polygon, nsides);
     383              : 
     384              :         // Function local variable declarations:
     385              :         int ip1;
     386              : 
     387        12980 :         inside = false;
     388              : 
     389        51920 :         for (int i = 1; i <= nsides; ++i) {
     390              : 
     391        38940 :             if (i < nsides) {
     392        25960 :                 ip1 = i + 1;
     393              :             } else {
     394        12980 :                 ip1 = 1;
     395              :             }
     396              : 
     397        38940 :             if ((polygon(i).y < point.y && point.y <= polygon(ip1).y) || (point.y <= polygon(i).y && polygon(ip1).y < point.y)) {
     398         9180 :                 if ((point.x - polygon(i).x) - (point.y - polygon(i).y) * (polygon(ip1).x - polygon(i).x) / (polygon(ip1).y - polygon(i).y) < 0) {
     399         4423 :                     inside = !inside;
     400              :                 }
     401              :             }
     402              :         }
     403              : 
     404        12980 :         return inside;
     405              :     }
     406              : 
     407          702 :     void generate_ears(EnergyPlusData &state,
     408              :                        int const nvert, // number of vertices in polygon
     409              :                        Array1D<Vector_2d> &vertex,
     410              :                        Array1D_int &ears,       // number of ears possible (dimensioned to nvert)
     411              :                        int &nears,              // number of ears found
     412              :                        Array1D_int &r_vertices, // number of reflex vertices (>180) possible
     413              :                        int &nrverts,            // number of reflex vertices found (>=180)
     414              :                        Array1D_int &c_vertices, // number of convex vertices
     415              :                        int &ncverts,            // number of convex vertices found (< 180)
     416              :                        Array1D_bool &removed,   // array that shows if a vertex has been removed (calling routine)
     417              :                        Array1D_int &earvert,    // vertex indicators for first ear
     418              :                        Array1D<Real64> &rangles)
     419              :     {
     420              : 
     421              :         // Subroutine information:
     422              :         //       Author         Linda Lawrie
     423              :         //       Date written   October 2005
     424              : 
     425              :         // Purpose of this subroutine:
     426              :         // This routine generates "ears", "reflex angles" and "convex angles" of the polygon
     427              :         // based on the method set for in the reference.
     428              : 
     429              :         // Methodology employed:
     430              :         // No elegance used here.  Always starts with first vertex in polygon.
     431              : 
     432              :         // References:
     433              :         // Geometric Tools for Computer Graphics, Philip Schneider, David Eberly. 2003.  Ear
     434              :         // clipping for triangulation is described in Chapter 13 on Polygon Partitioning.  Also
     435              :         // described in a small article "Triangulation by Ear Clipping", David Eberly, http://www.geometrictools.com
     436              : 
     437              :         // Argument array dimensioning
     438          702 :         EP_SIZE_CHECK(vertex, nvert);
     439          702 :         EP_SIZE_CHECK(ears, nvert);
     440          702 :         EP_SIZE_CHECK(r_vertices, nvert);
     441          702 :         EP_SIZE_CHECK(c_vertices, nvert);
     442          702 :         EP_SIZE_CHECK(removed, nvert);
     443          702 :         EP_SIZE_CHECK(earvert, 3);
     444          702 :         EP_SIZE_CHECK(rangles, nvert);
     445              : 
     446              :         // Subroutine local variable declarations:
     447              :         bool inpoly; // in polygon or not
     448              : 
     449              :         // Object Data
     450          702 :         Vector_2d point;               // structure for point
     451          702 :         Array1D<Vector_2d> testtri(3); // structure for triangle
     452              : 
     453              :         // initialize, always recalculate
     454          702 :         ears = 0;
     455          702 :         r_vertices = 0;
     456          702 :         rangles = 0.0;
     457          702 :         nears = 0;
     458          702 :         nrverts = 0;
     459          702 :         c_vertices = 0;
     460          702 :         ncverts = 0;
     461              : 
     462         6734 :         for (int svert = 1; svert <= nvert; ++svert) {
     463         6032 :             if (removed(svert)) {
     464         2713 :                 continue;
     465              :             }
     466              :             //  have starting vertex.  now need middle and end
     467         4420 :             int mvert = svert + 1;
     468         6032 :             for (int j = 1; j <= nvert; ++j) {
     469         6032 :                 if (mvert > nvert) {
     470          664 :                     mvert = 1;
     471              :                 }
     472         6032 :                 if (removed(mvert)) {
     473         1612 :                     ++mvert;
     474         1612 :                     if (mvert > nvert) {
     475           38 :                         mvert = 1;
     476              :                     }
     477              :                 } else {
     478         4420 :                     break;
     479              :                 }
     480              :             }
     481         4420 :             int evert = mvert + 1;
     482         6032 :             for (int j = 1; j <= nvert; ++j) {
     483         6032 :                 if (evert > nvert) {
     484          664 :                     evert = 1;
     485              :                 }
     486         6032 :                 if (removed(evert)) {
     487         1612 :                     ++evert;
     488         1612 :                     if (evert > nvert) {
     489           38 :                         evert = 1;
     490              :                     }
     491              :                 } else {
     492         4420 :                     break;
     493              :                 }
     494              :             }
     495              : 
     496              :             // have gotten start, middle and ending vertices.  test for reflex angle
     497              : 
     498         4420 :             Real64 ang = angle_2dvector(vertex(svert).x, vertex(svert).y, vertex(mvert).x, vertex(mvert).y, vertex(evert).x, vertex(evert).y);
     499              : 
     500         4420 :             if (ang > Constant::Pi) { // sufficiently close to 180 degrees.
     501         1101 :                 ++nrverts;
     502         1101 :                 r_vertices(nrverts) = mvert;
     503         1101 :                 rangles(nrverts) = ang;
     504         1101 :                 continue;
     505              :             } else {
     506         3319 :                 ++ncverts;
     507         3319 :                 c_vertices(ncverts) = mvert;
     508              :             }
     509              : 
     510              :             // convex angle, see if it's an ear
     511         3319 :             testtri(1) = vertex(svert);
     512         3319 :             testtri(2) = vertex(mvert);
     513         3319 :             testtri(3) = vertex(evert);
     514         3319 :             int tvert = evert;
     515        19878 :             for (int j = 4; j <= nvert; ++j) {
     516        17286 :                 ++tvert;
     517        17286 :                 if (tvert > nvert) {
     518         1864 :                     tvert = 1;
     519              :                 }
     520        17286 :                 if (removed(tvert)) {
     521         4306 :                     continue;
     522              :                 }
     523        12980 :                 point = vertex(tvert);
     524        12980 :                 inpoly = polygon_contains_point_2d(3, testtri, point);
     525        12980 :                 if (!inpoly) {
     526        12253 :                     continue;
     527              :                 }
     528          727 :                 break;
     529              :             }
     530              :             //    if (trackit) then
     531              :             //      write(outputfiledebug,*) ' triangle=',svert,mvert,evert
     532              :             //      write(outputfiledebug,*) ' vertex1=',vertex(svert)%x,vertex(svert)%y
     533              :             //      write(outputfiledebug,*) ' vertex2=',vertex(mvert)%x,vertex(mvert)%y
     534              :             //      write(outputfiledebug,*) ' vertex3=',vertex(evert)%x,vertex(evert)%y
     535              :             //      write(outputfiledebug,*) ' inpoly=',inpoly
     536              :             //    endif
     537         3319 :             if (!inpoly) {
     538              :                 // found an ear
     539         2592 :                 ++nears;
     540         2592 :                 ears(nears) = mvert;
     541         2592 :                 if (nears == 1) {
     542          701 :                     earvert(1) = svert;
     543          701 :                     earvert(2) = mvert;
     544          701 :                     earvert(3) = evert;
     545              :                 }
     546         2592 :                 if (state.dataDXFEarClipping->trackit) {
     547            0 :                     print(state.files.debug, "ear={} triangle={:12}{:12}{:12}\n", nears, svert, mvert, evert);
     548              :                 }
     549              :             }
     550              :         }
     551          702 :     }
     552              : 
     553            0 :     void CalcWallCoordinateTransformation(int const nsides,
     554              :                                           Array1D<Vector> &polygon,
     555              :                                           Real64 const surfazimuth,
     556              :                                           [[maybe_unused]] Real64 const surftilt, // unused1208
     557              :                                           Array1D<Real64> &xvt,
     558              :                                           Array1D<Real64> &yvt,
     559              :                                           Array1D<Real64> &zvt)
     560              :     {
     561              : 
     562              :         // Subroutine information:
     563              :         //       Author         Linda Lawrie
     564              :         //       Date written   October 2005
     565              : 
     566              :         // Purpose of this subroutine:
     567              :         // This routine transforms a "wall" (normally vertical polygon) to a south facing (180 deg outward
     568              :         // normal) polygon in 2 d (y vertices are then ignored).
     569              : 
     570              :         // Methodology employed:
     571              :         // Standard angle rotation
     572              : 
     573              :         // Argument array dimensioning
     574            0 :         EP_SIZE_CHECK(polygon, nsides);
     575            0 :         EP_SIZE_CHECK(xvt, nsides);
     576            0 :         EP_SIZE_CHECK(yvt, nsides);
     577            0 :         EP_SIZE_CHECK(zvt, nsides);
     578              : 
     579              :         // convert surface (wall) to facing 180 (outward normal)
     580              : 
     581            0 :         Real64 const alpha = surfazimuth;
     582              : 
     583            0 :         Real64 const alpha180 = 180.0 - alpha; // amount to rotate
     584            0 :         Real64 const alphrad = alpha180 / Constant::RadToDeg;
     585            0 :         Real64 const cos_alphrad = std::cos(alphrad);
     586            0 :         Real64 const sin_alphrad = std::sin(alphrad);
     587              : 
     588            0 :         for (int i = 1; i <= nsides; ++i) {
     589            0 :             xvt(i) = cos_alphrad * polygon(i).x + sin_alphrad * polygon(i).y;
     590            0 :             yvt(i) = -sin_alphrad * polygon(i).x + cos_alphrad * polygon(i).y;
     591            0 :             zvt(i) = polygon(i).z;
     592              :         }
     593            0 :     }
     594              : 
     595          142 :     void CalcRfFlrCoordinateTransformation(int const nsides,
     596              :                                            Array1D<Vector> &polygon,
     597              :                                            [[maybe_unused]] Real64 const surfazimuth, // unused1208
     598              :                                            Real64 const surftilt,
     599              :                                            Array1D<Real64> &xvt,
     600              :                                            Array1D<Real64> &yvt,
     601              :                                            Array1D<Real64> &zvt)
     602              :     {
     603              : 
     604              :         // Subroutine information:
     605              :         //       Author         Linda Lawrie
     606              :         //       Date written   October 2005
     607              : 
     608              :         // Purpose of this subroutine:
     609              :         // This routine transforms a roof/floor (normally flat polygon) to a flat
     610              :         // polygon in 2 d (z vertices are then ignored).
     611              : 
     612              :         // Standard angle rotation
     613              : 
     614              :         // Argument array dimensioning
     615          142 :         EP_SIZE_CHECK(polygon, nsides);
     616          142 :         EP_SIZE_CHECK(xvt, nsides);
     617          142 :         EP_SIZE_CHECK(yvt, nsides);
     618          142 :         EP_SIZE_CHECK(zvt, nsides);
     619              : 
     620              :         // Subroutine local variable declarations:
     621              : 
     622          142 :         Real64 const alpha = -surftilt;
     623          142 :         Real64 const alphrad = alpha / Constant::RadToDeg;
     624          142 :         Real64 const cos_alphrad = std::cos(alphrad);
     625          142 :         Real64 const sin_alphrad = std::sin(alphrad);
     626              : 
     627         1270 :         for (int i = 1; i <= nsides; ++i) {
     628         1128 :             xvt(i) = polygon(i).x;
     629         1128 :             yvt(i) = cos_alphrad * polygon(i).x + sin_alphrad * polygon(i).y;
     630         1128 :             zvt(i) = -sin_alphrad * polygon(i).x + cos_alphrad * polygon(i).y;
     631              :         }
     632          142 :     }
     633              : 
     634              :     // void reorder([[maybe_unused]] int &nvert) // unused1208
     635              :     //{
     636              : 
     637              :     //    // Locals
     638              :     //    // type (Vector_2d) nvertex(nvert)
     639              :     //    // integer i
     640              :     //    // type (Vector_2d) point
     641              :     //    // integer nrep
     642              : 
     643              :     //    //  Vertex, nverts is in cw order, reorder for calc
     644              : 
     645              :     //    // nrep=1
     646              :     //    // nvertex(1)=vertex(1)
     647              :     //    // do i=nvert,1,-1
     648              :     //    //  nvertex(nrep)=vertex(i)
     649              :     //    //  nrep=nrep+1
     650              :     //    // enddo
     651              :     //    // do i=1,nvert
     652              :     //    //  vertex(i)=nvertex(i)
     653              :     //    // enddo
     654              :     //}
     655              : 
     656              : } // namespace DXFEarClipping
     657              : 
     658              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1