LCOV - code coverage report
Current view: top level - EnergyPlus - DXFEarClipping.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 171 230 74.3 %
Date: 2024-08-23 23:50:59 Functions: 5 8 62.5 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, 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         284 :         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) xvt(svert) = xvt(mvert);
     202        4144 :                     if (std::abs(zvt(svert) - zvt(mvert)) <= point_tolerance) zvt(svert) = zvt(mvert);
     203             :                 }
     204             :             }
     205        1270 :             for (int svert = 1; svert <= nsides; ++svert) {
     206        1128 :                 vertex(svert).x = xvt(svert);
     207        1128 :                 vertex(svert).y = zvt(svert);
     208             :                 //      if (trackit) write(outputfiledebug,*) 'x=',xvt(svert),' y=',zvt(svert)
     209             :             }
     210         142 :         } 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         142 :         int nvertcur = nsides;
     226         142 :         int ncount = 0;
     227         142 :         int svert = 1;
     228         142 :         int mvert = 2;
     229         142 :         int evert = 3;
     230         142 :         removed = false;
     231         843 :         while (nvertcur > 3) {
     232         702 :             generate_ears(state, nsides, vertex, ears, nears, r_angles, nrangles, c_vertices, ncverts, removed, earverts, rangles);
     233         702 :             if (!any_gt(ears, 0)) {
     234           2 :                 ShowWarningError(state,
     235           2 :                                  format("DXFOut: Could not triangulate surface=\"{}\", type=\"{}\", check surface vertex order(entry)",
     236             :                                         surfname,
     237           2 :                                         DataSurfaces::cSurfaceClass(surfclass)));
     238           1 :                 ++state.dataDXFEarClipping->errcount;
     239           1 :                 if (state.dataDXFEarClipping->errcount == 1 && !state.dataGlobal->DisplayExtraWarnings) {
     240           1 :                     ShowContinueError(state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on individual surfaces.");
     241             :                 }
     242           1 :                 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           1 :                 break; // while loop
     254             :             }
     255         701 :             if (nears > 0) {
     256         701 :                 svert = earverts(1);
     257         701 :                 mvert = earverts(2);
     258         701 :                 evert = earverts(3);
     259             :                 // remove ear
     260         701 :                 ++ncount;
     261         701 :                 removed(mvert) = true;
     262         701 :                 earvert(ncount, 1) = svert;
     263         701 :                 earvert(ncount, 2) = mvert;
     264         701 :                 earvert(ncount, 3) = evert;
     265         701 :                 --nvertcur;
     266             :             }
     267         701 :             if (nvertcur == 3) {
     268         141 :                 int j = 1;
     269         141 :                 ++ncount;
     270        1261 :                 for (int i = 1; i <= nsides; ++i) {
     271        1120 :                     if (removed(i)) continue;
     272         423 :                     earvert(ncount, j) = i;
     273         423 :                     ++j;
     274             :                 }
     275             :             }
     276             :         }
     277             : 
     278         142 :         int ntri = ncount;
     279             : 
     280         984 :         for (int i = 1; i <= ntri; ++i) {
     281         842 :             Triangle(i).vv0 = earvert(i, 1);
     282         842 :             Triangle(i).vv1 = earvert(i, 2);
     283         842 :             Triangle(i).vv2 = earvert(i, 3);
     284             :         }
     285             : 
     286         142 :         outtriangles.allocate(ntri);
     287         984 :         for (int i = 1; i <= ntri; ++i) {
     288         842 :             outtriangles(i) = Triangle(i);
     289             :         }
     290             : 
     291         142 :         return ntri;
     292         142 :     }
     293             : 
     294        4420 :     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        4420 :         Real64 constexpr epsilon(0.0000001);
     324             : 
     325        4420 :         Real64 x1 = xa - xb;
     326        4420 :         Real64 y1 = ya - yb;
     327        4420 :         Real64 x2 = xc - xb;
     328        4420 :         Real64 y2 = yc - yb;
     329             : 
     330        4420 :         Real64 t = std::sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2));
     331        4420 :         if (t == 0.0E+00) t = 1.0E+00;
     332             : 
     333        4420 :         t = (x1 * x2 + y1 * y2) / t;
     334             : 
     335        4420 :         if ((1.0E+00 - epsilon) < std::abs(t)) {
     336          81 :             t = sign(1.0E+00, t);
     337             :         }
     338             : 
     339        4420 :         angle = std::acos(t);
     340             : 
     341        4420 :         if (x2 * y1 - y2 * x1 < 0.0E+00) {
     342        1102 :             angle = 2.0E+00 * Constant::Pi - angle;
     343             :         }
     344             : 
     345        4420 :         return angle;
     346             :     }
     347             : 
     348       12980 :     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       12980 :         EP_SIZE_CHECK(polygon, nsides);
     371             : 
     372             :         // Function local variable declarations:
     373             :         int ip1;
     374             : 
     375       12980 :         inside = false;
     376             : 
     377       51920 :         for (int i = 1; i <= nsides; ++i) {
     378             : 
     379       38940 :             if (i < nsides) {
     380       25960 :                 ip1 = i + 1;
     381             :             } else {
     382       12980 :                 ip1 = 1;
     383             :             }
     384             : 
     385       38940 :             if ((polygon(i).y < point.y && point.y <= polygon(ip1).y) || (point.y <= polygon(i).y && polygon(ip1).y < point.y)) {
     386        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) {
     387        4423 :                     inside = !inside;
     388             :                 }
     389             :             }
     390             :         }
     391             : 
     392       12980 :         return inside;
     393             :     }
     394             : 
     395         702 :     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         702 :         EP_SIZE_CHECK(vertex, nvert);
     427         702 :         EP_SIZE_CHECK(ears, nvert);
     428         702 :         EP_SIZE_CHECK(r_vertices, nvert);
     429         702 :         EP_SIZE_CHECK(c_vertices, nvert);
     430         702 :         EP_SIZE_CHECK(removed, nvert);
     431         702 :         EP_SIZE_CHECK(earvert, 3);
     432         702 :         EP_SIZE_CHECK(rangles, nvert);
     433             : 
     434             :         // Subroutine local variable declarations:
     435             :         bool inpoly; // in polygon or not
     436             : 
     437             :         // Object Data
     438         702 :         Vector_2d point;               // structure for point
     439         702 :         Array1D<Vector_2d> testtri(3); // structure for triangle
     440             : 
     441             :         // initialize, always recalculate
     442         702 :         ears = 0;
     443         702 :         r_vertices = 0;
     444         702 :         rangles = 0.0;
     445         702 :         nears = 0;
     446         702 :         nrverts = 0;
     447         702 :         c_vertices = 0;
     448         702 :         ncverts = 0;
     449             : 
     450        6734 :         for (int svert = 1; svert <= nvert; ++svert) {
     451        7133 :             if (removed(svert)) continue;
     452             :             //  have starting vertex.  now need middle and end
     453        4420 :             int mvert = svert + 1;
     454        6032 :             for (int j = 1; j <= nvert; ++j) {
     455        6032 :                 if (mvert > nvert) mvert = 1;
     456        6032 :                 if (removed(mvert)) {
     457        1612 :                     ++mvert;
     458        1612 :                     if (mvert > nvert) mvert = 1;
     459             :                 } else {
     460        4420 :                     break;
     461             :                 }
     462             :             }
     463        4420 :             int evert = mvert + 1;
     464        6032 :             for (int j = 1; j <= nvert; ++j) {
     465        6032 :                 if (evert > nvert) evert = 1;
     466        6032 :                 if (removed(evert)) {
     467        1612 :                     ++evert;
     468        1612 :                     if (evert > nvert) evert = 1;
     469             :                 } else {
     470        4420 :                     break;
     471             :                 }
     472             :             }
     473             : 
     474             :             // have gotten start, middle and ending vertices.  test for reflex angle
     475             : 
     476        4420 :             Real64 ang = angle_2dvector(vertex(svert).x, vertex(svert).y, vertex(mvert).x, vertex(mvert).y, vertex(evert).x, vertex(evert).y);
     477             : 
     478        4420 :             if (ang > Constant::Pi) { // sufficiently close to 180 degrees.
     479        1101 :                 ++nrverts;
     480        1101 :                 r_vertices(nrverts) = mvert;
     481        1101 :                 rangles(nrverts) = ang;
     482        1101 :                 continue;
     483             :             } else {
     484        3319 :                 ++ncverts;
     485        3319 :                 c_vertices(ncverts) = mvert;
     486             :             }
     487             : 
     488             :             // convex angle, see if it's an ear
     489        3319 :             testtri(1) = vertex(svert);
     490        3319 :             testtri(2) = vertex(mvert);
     491        3319 :             testtri(3) = vertex(evert);
     492        3319 :             int tvert = evert;
     493       19878 :             for (int j = 4; j <= nvert; ++j) {
     494       17286 :                 ++tvert;
     495       17286 :                 if (tvert > nvert) tvert = 1;
     496       17286 :                 if (removed(tvert)) continue;
     497       12980 :                 point = vertex(tvert);
     498       12980 :                 inpoly = polygon_contains_point_2d(3, testtri, point);
     499       12980 :                 if (!inpoly) continue;
     500         727 :                 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        3319 :             if (!inpoly) {
     510             :                 // found an ear
     511        2592 :                 ++nears;
     512        2592 :                 ears(nears) = mvert;
     513        2592 :                 if (nears == 1) {
     514         701 :                     earvert(1) = svert;
     515         701 :                     earvert(2) = mvert;
     516         701 :                     earvert(3) = evert;
     517             :                 }
     518        2592 :                 if (state.dataDXFEarClipping->trackit) {
     519           0 :                     print(state.files.debug, "ear={} triangle={:12}{:12}{:12}\n", nears, svert, mvert, evert);
     520             :                 }
     521             :             }
     522             :         }
     523         702 :     }
     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         142 :     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         142 :         EP_SIZE_CHECK(polygon, nsides);
     588         142 :         EP_SIZE_CHECK(xvt, nsides);
     589         142 :         EP_SIZE_CHECK(yvt, nsides);
     590         142 :         EP_SIZE_CHECK(zvt, nsides);
     591             : 
     592             :         // Subroutine local variable declarations:
     593             : 
     594         142 :         Real64 const alpha = -surftilt;
     595         142 :         Real64 const alphrad = alpha / Constant::RadToDeg;
     596         142 :         Real64 const cos_alphrad = std::cos(alphrad);
     597         142 :         Real64 const sin_alphrad = std::sin(alphrad);
     598             : 
     599        1270 :         for (int i = 1; i <= nsides; ++i) {
     600        1128 :             xvt(i) = polygon(i).x;
     601        1128 :             yvt(i) = cos_alphrad * polygon(i).x + sin_alphrad * polygon(i).y;
     602        1128 :             zvt(i) = -sin_alphrad * polygon(i).x + cos_alphrad * polygon(i).y;
     603             :         }
     604         142 :     }
     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 1.14