LCOV - code coverage report
Current view: top level - EnergyPlus - DXFEarClipping.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 0.0 % 230 0
Test Date: 2025-05-22 16:09:37 Functions: 0.0 % 8 0

            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            0 :     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            0 :         EP_SIZE_CHECK(polygon, nsides);
     172              : 
     173              :         // Subroutine parameter definitions:
     174            0 :         Real64 constexpr point_tolerance(0.00001);
     175              : 
     176              :         // Subroutine local variable declarations:
     177            0 :         Array1D_int ears(nsides);
     178            0 :         Array1D_int r_angles(nsides);
     179            0 :         Array1D<Real64> rangles(nsides);
     180            0 :         Array1D_int c_vertices(nsides);
     181            0 :         Array2D_int earvert(nsides, 3);
     182            0 :         Array1D_bool removed(nsides);
     183            0 :         Array1D_int earverts(3);
     184            0 :         Array1D<Real64> xvt(nsides);
     185            0 :         Array1D<Real64> yvt(nsides);
     186            0 :         Array1D<Real64> zvt(nsides);
     187              : 
     188              :         int nears;
     189              :         int nrangles;
     190              :         int ncverts;
     191              : 
     192              :         // Object Data
     193            0 :         Array1D<Vector_2d> vertex(nsides);
     194            0 :         Array1D<dTriangle> Triangle(nsides);
     195              : 
     196            0 :         if (surfclass == DataSurfaces::SurfaceClass::Floor || surfclass == DataSurfaces::SurfaceClass::Roof ||
     197              :             surfclass == DataSurfaces::SurfaceClass::Overhang) {
     198            0 :             CalcRfFlrCoordinateTransformation(nsides, polygon, surfazimuth, surftilt, xvt, yvt, zvt);
     199            0 :             for (int svert = 1; svert <= nsides; ++svert) {
     200            0 :                 for (int mvert = svert + 1; mvert <= nsides; ++mvert) {
     201            0 :                     if (std::abs(xvt(svert) - xvt(mvert)) <= point_tolerance) xvt(svert) = xvt(mvert);
     202            0 :                     if (std::abs(zvt(svert) - zvt(mvert)) <= point_tolerance) zvt(svert) = zvt(mvert);
     203              :                 }
     204              :             }
     205            0 :             for (int svert = 1; svert <= nsides; ++svert) {
     206            0 :                 vertex(svert).x = xvt(svert);
     207            0 :                 vertex(svert).y = zvt(svert);
     208              :                 //      if (trackit) write(outputfiledebug,*) 'x=',xvt(svert),' y=',zvt(svert)
     209              :             }
     210            0 :         } else {
     211            0 :             CalcWallCoordinateTransformation(nsides, polygon, surfazimuth, surftilt, xvt, yvt, zvt);
     212            0 :             for (int svert = 1; svert <= nsides; ++svert) {
     213            0 :                 for (int mvert = svert + 1; mvert <= nsides; ++mvert) {
     214            0 :                     if (std::abs(xvt(svert) - xvt(mvert)) <= point_tolerance) xvt(svert) = xvt(mvert);
     215            0 :                     if (std::abs(zvt(svert) - zvt(mvert)) <= point_tolerance) zvt(svert) = zvt(mvert);
     216              :                 }
     217              :             }
     218            0 :             for (int svert = 1; svert <= nsides; ++svert) {
     219            0 :                 vertex(svert).x = xvt(svert);
     220            0 :                 vertex(svert).y = zvt(svert);
     221              :             }
     222              :         }
     223              : 
     224              :         // find ears
     225            0 :         int nvertcur = nsides;
     226            0 :         int ncount = 0;
     227            0 :         int svert = 1;
     228            0 :         int mvert = 2;
     229            0 :         int evert = 3;
     230            0 :         removed = false;
     231            0 :         while (nvertcur > 3) {
     232            0 :             generate_ears(state, nsides, vertex, ears, nears, r_angles, nrangles, c_vertices, ncverts, removed, earverts, rangles);
     233            0 :             if (!any_gt(ears, 0)) {
     234            0 :                 ShowWarningError(state,
     235            0 :                                  format("DXFOut: Could not triangulate surface=\"{}\", type=\"{}\", check surface vertex order(entry)",
     236              :                                         surfname,
     237            0 :                                         DataSurfaces::cSurfaceClass(surfclass)));
     238            0 :                 ++state.dataDXFEarClipping->errcount;
     239            0 :                 if (state.dataDXFEarClipping->errcount == 1 && !state.dataGlobal->DisplayExtraWarnings) {
     240            0 :                     ShowContinueError(state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on individual surfaces.");
     241              :                 }
     242            0 :                 if (state.dataGlobal->DisplayExtraWarnings) {
     243            0 :                     ShowMessage(state, format(" surface={} class={}", surfname, DataSurfaces::cSurfaceClass(surfclass)));
     244              : 
     245            0 :                     for (int j = 1; j <= nsides; ++j) {
     246            0 :                         ShowMessage(state, format(" side={} ({:.1R},{:.1R},{:.1R})", j, polygon(j).x, polygon(j).y, polygon(j).z));
     247              :                     }
     248            0 :                     ShowMessage(state, format(" number of triangles found={:12}", ncount));
     249            0 :                     for (int j = 1; j <= nrangles; ++j) {
     250            0 :                         ShowMessage(state, format(" r angle={} vert={} deg={:.1R}", j, r_angles(j), rangles(j) * Constant::RadToDeg));
     251              :                     }
     252              :                 }
     253            0 :                 break; // while loop
     254              :             }
     255            0 :             if (nears > 0) {
     256            0 :                 svert = earverts(1);
     257            0 :                 mvert = earverts(2);
     258            0 :                 evert = earverts(3);
     259              :                 // remove ear
     260            0 :                 ++ncount;
     261            0 :                 removed(mvert) = true;
     262            0 :                 earvert(ncount, 1) = svert;
     263            0 :                 earvert(ncount, 2) = mvert;
     264            0 :                 earvert(ncount, 3) = evert;
     265            0 :                 --nvertcur;
     266              :             }
     267            0 :             if (nvertcur == 3) {
     268            0 :                 int j = 1;
     269            0 :                 ++ncount;
     270            0 :                 for (int i = 1; i <= nsides; ++i) {
     271            0 :                     if (removed(i)) continue;
     272            0 :                     earvert(ncount, j) = i;
     273            0 :                     ++j;
     274              :                 }
     275              :             }
     276              :         }
     277              : 
     278            0 :         int ntri = ncount;
     279              : 
     280            0 :         for (int i = 1; i <= ntri; ++i) {
     281            0 :             Triangle(i).vv0 = earvert(i, 1);
     282            0 :             Triangle(i).vv1 = earvert(i, 2);
     283            0 :             Triangle(i).vv2 = earvert(i, 3);
     284              :         }
     285              : 
     286            0 :         outtriangles.allocate(ntri);
     287            0 :         for (int i = 1; i <= ntri; ++i) {
     288            0 :             outtriangles(i) = Triangle(i);
     289              :         }
     290              : 
     291            0 :         return ntri;
     292            0 :     }
     293              : 
     294            0 :     Real64 angle_2dvector(Real64 const xa, // vertex coordinate
     295              :                           Real64 const ya, // vertex coordinate
     296              :                           Real64 const xb, // vertex coordinate
     297              :                           Real64 const yb, // vertex coordinate
     298              :                           Real64 const xc, // vertex coordinate
     299              :                           Real64 const yc  // vertex coordinate
     300              :     )
     301              :     {
     302              : 
     303              :         // Function information:
     304              :         //       Author         Linda Lawrie
     305              :         //       Date written   October 2005
     306              : 
     307              :         // Purpose of this function:
     308              :         // This function calculates the angle between two sides of a 2d polygon.
     309              :         // It computes the interior angle in radians at vertex
     310              :         // (XB,YB) of the chain formed by the directed edges from
     311              :         // (XA,YA) to (XB,YB) to (XC,YC).  The interior is to the
     312              :         // left of the two directed edges.
     313              : 
     314              :         // References:
     315              :         // Geometry Tools for Computer Graphics
     316              : 
     317              :         // Return value
     318              :         Real64 angle; // the angle, between 0 and 2*PI.
     319              : 
     320              :         // angle is set to PI/2 in the degenerate case.
     321              : 
     322              :         // Function parameter definitions:
     323            0 :         Real64 constexpr epsilon(0.0000001);
     324              : 
     325            0 :         Real64 x1 = xa - xb;
     326            0 :         Real64 y1 = ya - yb;
     327            0 :         Real64 x2 = xc - xb;
     328            0 :         Real64 y2 = yc - yb;
     329              : 
     330            0 :         Real64 t = std::sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2));
     331            0 :         if (t == 0.0E+00) t = 1.0E+00;
     332              : 
     333            0 :         t = (x1 * x2 + y1 * y2) / t;
     334              : 
     335            0 :         if ((1.0E+00 - epsilon) < std::abs(t)) {
     336            0 :             t = sign(1.0E+00, t);
     337              :         }
     338              : 
     339            0 :         angle = std::acos(t);
     340              : 
     341            0 :         if (x2 * y1 - y2 * x1 < 0.0E+00) {
     342            0 :             angle = 2.0E+00 * Constant::Pi - angle;
     343              :         }
     344              : 
     345            0 :         return angle;
     346              :     }
     347              : 
     348            0 :     bool polygon_contains_point_2d(int const nsides,            // number of sides (vertices)
     349              :                                    Array1D<Vector_2d> &polygon, // points of polygon
     350              :                                    Vector_2d const &point       // point to be tested
     351              :     )
     352              :     {
     353              : 
     354              :         // Function information:
     355              :         //       Author         Linda Lawrie
     356              :         //       Date written   October 2005
     357              : 
     358              :         // Purpose of this function:
     359              :         // Determine if a point is inside a simple 2d polygon.  For a simple polygon (one whose
     360              :         // boundary never crosses itself).  The polygon does not need to be convex.
     361              : 
     362              :         // References:
     363              :         // M Shimrat, Position of Point Relative to Polygon, ACM Algorithm 112,
     364              :         // Communications of the ACM, Volume 5, Number 8, page 434, August 1962.
     365              : 
     366              :         // Return value
     367              :         bool inside; // return value, true=inside, false = not inside
     368              : 
     369              :         // Argument array dimensioning
     370            0 :         EP_SIZE_CHECK(polygon, nsides);
     371              : 
     372              :         // Function local variable declarations:
     373              :         int ip1;
     374              : 
     375            0 :         inside = false;
     376              : 
     377            0 :         for (int i = 1; i <= nsides; ++i) {
     378              : 
     379            0 :             if (i < nsides) {
     380            0 :                 ip1 = i + 1;
     381              :             } else {
     382            0 :                 ip1 = 1;
     383              :             }
     384              : 
     385            0 :             if ((polygon(i).y < point.y && point.y <= polygon(ip1).y) || (point.y <= polygon(i).y && polygon(ip1).y < point.y)) {
     386            0 :                 if ((point.x - polygon(i).x) - (point.y - polygon(i).y) * (polygon(ip1).x - polygon(i).x) / (polygon(ip1).y - polygon(i).y) < 0) {
     387            0 :                     inside = !inside;
     388              :                 }
     389              :             }
     390              :         }
     391              : 
     392            0 :         return inside;
     393              :     }
     394              : 
     395            0 :     void generate_ears(EnergyPlusData &state,
     396              :                        int const nvert, // number of vertices in polygon
     397              :                        Array1D<Vector_2d> &vertex,
     398              :                        Array1D_int &ears,       // number of ears possible (dimensioned to nvert)
     399              :                        int &nears,              // number of ears found
     400              :                        Array1D_int &r_vertices, // number of reflex vertices (>180) possible
     401              :                        int &nrverts,            // number of reflex vertices found (>=180)
     402              :                        Array1D_int &c_vertices, // number of convex vertices
     403              :                        int &ncverts,            // number of convex vertices found (< 180)
     404              :                        Array1D_bool &removed,   // array that shows if a vertex has been removed (calling routine)
     405              :                        Array1D_int &earvert,    // vertex indicators for first ear
     406              :                        Array1D<Real64> &rangles)
     407              :     {
     408              : 
     409              :         // Subroutine information:
     410              :         //       Author         Linda Lawrie
     411              :         //       Date written   October 2005
     412              : 
     413              :         // Purpose of this subroutine:
     414              :         // This routine generates "ears", "reflex angles" and "convex angles" of the polygon
     415              :         // based on the method set for in the reference.
     416              : 
     417              :         // Methodology employed:
     418              :         // No elegance used here.  Always starts with first vertex in polygon.
     419              : 
     420              :         // References:
     421              :         // Geometric Tools for Computer Graphics, Philip Schneider, David Eberly. 2003.  Ear
     422              :         // clipping for triangulation is described in Chapter 13 on Polygon Partitioning.  Also
     423              :         // described in a small article "Triangulation by Ear Clipping", David Eberly, http://www.geometrictools.com
     424              : 
     425              :         // Argument array dimensioning
     426            0 :         EP_SIZE_CHECK(vertex, nvert);
     427            0 :         EP_SIZE_CHECK(ears, nvert);
     428            0 :         EP_SIZE_CHECK(r_vertices, nvert);
     429            0 :         EP_SIZE_CHECK(c_vertices, nvert);
     430            0 :         EP_SIZE_CHECK(removed, nvert);
     431            0 :         EP_SIZE_CHECK(earvert, 3);
     432            0 :         EP_SIZE_CHECK(rangles, nvert);
     433              : 
     434              :         // Subroutine local variable declarations:
     435              :         bool inpoly; // in polygon or not
     436              : 
     437              :         // Object Data
     438            0 :         Vector_2d point;               // structure for point
     439            0 :         Array1D<Vector_2d> testtri(3); // structure for triangle
     440              : 
     441              :         // initialize, always recalculate
     442            0 :         ears = 0;
     443            0 :         r_vertices = 0;
     444            0 :         rangles = 0.0;
     445            0 :         nears = 0;
     446            0 :         nrverts = 0;
     447            0 :         c_vertices = 0;
     448            0 :         ncverts = 0;
     449              : 
     450            0 :         for (int svert = 1; svert <= nvert; ++svert) {
     451            0 :             if (removed(svert)) continue;
     452              :             //  have starting vertex.  now need middle and end
     453            0 :             int mvert = svert + 1;
     454            0 :             for (int j = 1; j <= nvert; ++j) {
     455            0 :                 if (mvert > nvert) mvert = 1;
     456            0 :                 if (removed(mvert)) {
     457            0 :                     ++mvert;
     458            0 :                     if (mvert > nvert) mvert = 1;
     459              :                 } else {
     460            0 :                     break;
     461              :                 }
     462              :             }
     463            0 :             int evert = mvert + 1;
     464            0 :             for (int j = 1; j <= nvert; ++j) {
     465            0 :                 if (evert > nvert) evert = 1;
     466            0 :                 if (removed(evert)) {
     467            0 :                     ++evert;
     468            0 :                     if (evert > nvert) evert = 1;
     469              :                 } else {
     470            0 :                     break;
     471              :                 }
     472              :             }
     473              : 
     474              :             // have gotten start, middle and ending vertices.  test for reflex angle
     475              : 
     476            0 :             Real64 ang = angle_2dvector(vertex(svert).x, vertex(svert).y, vertex(mvert).x, vertex(mvert).y, vertex(evert).x, vertex(evert).y);
     477              : 
     478            0 :             if (ang > Constant::Pi) { // sufficiently close to 180 degrees.
     479            0 :                 ++nrverts;
     480            0 :                 r_vertices(nrverts) = mvert;
     481            0 :                 rangles(nrverts) = ang;
     482            0 :                 continue;
     483              :             } else {
     484            0 :                 ++ncverts;
     485            0 :                 c_vertices(ncverts) = mvert;
     486              :             }
     487              : 
     488              :             // convex angle, see if it's an ear
     489            0 :             testtri(1) = vertex(svert);
     490            0 :             testtri(2) = vertex(mvert);
     491            0 :             testtri(3) = vertex(evert);
     492            0 :             int tvert = evert;
     493            0 :             for (int j = 4; j <= nvert; ++j) {
     494            0 :                 ++tvert;
     495            0 :                 if (tvert > nvert) tvert = 1;
     496            0 :                 if (removed(tvert)) continue;
     497            0 :                 point = vertex(tvert);
     498            0 :                 inpoly = polygon_contains_point_2d(3, testtri, point);
     499            0 :                 if (!inpoly) continue;
     500            0 :                 break;
     501              :             }
     502              :             //    if (trackit) then
     503              :             //      write(outputfiledebug,*) ' triangle=',svert,mvert,evert
     504              :             //      write(outputfiledebug,*) ' vertex1=',vertex(svert)%x,vertex(svert)%y
     505              :             //      write(outputfiledebug,*) ' vertex2=',vertex(mvert)%x,vertex(mvert)%y
     506              :             //      write(outputfiledebug,*) ' vertex3=',vertex(evert)%x,vertex(evert)%y
     507              :             //      write(outputfiledebug,*) ' inpoly=',inpoly
     508              :             //    endif
     509            0 :             if (!inpoly) {
     510              :                 // found an ear
     511            0 :                 ++nears;
     512            0 :                 ears(nears) = mvert;
     513            0 :                 if (nears == 1) {
     514            0 :                     earvert(1) = svert;
     515            0 :                     earvert(2) = mvert;
     516            0 :                     earvert(3) = evert;
     517              :                 }
     518            0 :                 if (state.dataDXFEarClipping->trackit) {
     519            0 :                     print(state.files.debug, "ear={} triangle={:12}{:12}{:12}\n", nears, svert, mvert, evert);
     520              :                 }
     521              :             }
     522              :         }
     523            0 :     }
     524              : 
     525            0 :     void CalcWallCoordinateTransformation(int const nsides,
     526              :                                           Array1D<Vector> &polygon,
     527              :                                           Real64 const surfazimuth,
     528              :                                           [[maybe_unused]] Real64 const surftilt, // unused1208
     529              :                                           Array1D<Real64> &xvt,
     530              :                                           Array1D<Real64> &yvt,
     531              :                                           Array1D<Real64> &zvt)
     532              :     {
     533              : 
     534              :         // Subroutine information:
     535              :         //       Author         Linda Lawrie
     536              :         //       Date written   October 2005
     537              : 
     538              :         // Purpose of this subroutine:
     539              :         // This routine transforms a "wall" (normally vertical polygon) to a south facing (180 deg outward
     540              :         // normal) polygon in 2 d (y vertices are then ignored).
     541              : 
     542              :         // Methodology employed:
     543              :         // Standard angle rotation
     544              : 
     545              :         // Argument array dimensioning
     546            0 :         EP_SIZE_CHECK(polygon, nsides);
     547            0 :         EP_SIZE_CHECK(xvt, nsides);
     548            0 :         EP_SIZE_CHECK(yvt, nsides);
     549            0 :         EP_SIZE_CHECK(zvt, nsides);
     550              : 
     551              :         // convert surface (wall) to facing 180 (outward normal)
     552              : 
     553            0 :         Real64 const alpha = surfazimuth;
     554              : 
     555            0 :         Real64 const alpha180 = 180.0 - alpha; // amount to rotate
     556            0 :         Real64 const alphrad = alpha180 / Constant::RadToDeg;
     557            0 :         Real64 const cos_alphrad = std::cos(alphrad);
     558            0 :         Real64 const sin_alphrad = std::sin(alphrad);
     559              : 
     560            0 :         for (int i = 1; i <= nsides; ++i) {
     561            0 :             xvt(i) = cos_alphrad * polygon(i).x + sin_alphrad * polygon(i).y;
     562            0 :             yvt(i) = -sin_alphrad * polygon(i).x + cos_alphrad * polygon(i).y;
     563            0 :             zvt(i) = polygon(i).z;
     564              :         }
     565            0 :     }
     566              : 
     567            0 :     void CalcRfFlrCoordinateTransformation(int const nsides,
     568              :                                            Array1D<Vector> &polygon,
     569              :                                            [[maybe_unused]] Real64 const surfazimuth, // unused1208
     570              :                                            Real64 const surftilt,
     571              :                                            Array1D<Real64> &xvt,
     572              :                                            Array1D<Real64> &yvt,
     573              :                                            Array1D<Real64> &zvt)
     574              :     {
     575              : 
     576              :         // Subroutine information:
     577              :         //       Author         Linda Lawrie
     578              :         //       Date written   October 2005
     579              : 
     580              :         // Purpose of this subroutine:
     581              :         // This routine transforms a roof/floor (normally flat polygon) to a flat
     582              :         // polygon in 2 d (z vertices are then ignored).
     583              : 
     584              :         // Standard angle rotation
     585              : 
     586              :         // Argument array dimensioning
     587            0 :         EP_SIZE_CHECK(polygon, nsides);
     588            0 :         EP_SIZE_CHECK(xvt, nsides);
     589            0 :         EP_SIZE_CHECK(yvt, nsides);
     590            0 :         EP_SIZE_CHECK(zvt, nsides);
     591              : 
     592              :         // Subroutine local variable declarations:
     593              : 
     594            0 :         Real64 const alpha = -surftilt;
     595            0 :         Real64 const alphrad = alpha / Constant::RadToDeg;
     596            0 :         Real64 const cos_alphrad = std::cos(alphrad);
     597            0 :         Real64 const sin_alphrad = std::sin(alphrad);
     598              : 
     599            0 :         for (int i = 1; i <= nsides; ++i) {
     600            0 :             xvt(i) = polygon(i).x;
     601            0 :             yvt(i) = cos_alphrad * polygon(i).x + sin_alphrad * polygon(i).y;
     602            0 :             zvt(i) = -sin_alphrad * polygon(i).x + cos_alphrad * polygon(i).y;
     603              :         }
     604            0 :     }
     605              : 
     606              :     // void reorder([[maybe_unused]] int &nvert) // unused1208
     607              :     //{
     608              : 
     609              :     //    // Locals
     610              :     //    // type (Vector_2d) nvertex(nvert)
     611              :     //    // integer i
     612              :     //    // type (Vector_2d) point
     613              :     //    // integer nrep
     614              : 
     615              :     //    //  Vertex, nverts is in cw order, reorder for calc
     616              : 
     617              :     //    // nrep=1
     618              :     //    // nvertex(1)=vertex(1)
     619              :     //    // do i=nvert,1,-1
     620              :     //    //  nvertex(nrep)=vertex(i)
     621              :     //    //  nrep=nrep+1
     622              :     //    // enddo
     623              :     //    // do i=1,nvert
     624              :     //    //  vertex(i)=nvertex(i)
     625              :     //    // enddo
     626              :     //}
     627              : 
     628              : } // namespace DXFEarClipping
     629              : 
     630              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1