LCOV - code coverage report
Current view: top level - EnergyPlus - DXFEarClipping.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 172 232 74.1 %
Date: 2023-01-17 19:17:23 Functions: 7 11 63.6 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, 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             :     //       Modified       na
      71             :     //       Re-engineered  na
      72             : 
      73             :     // Purpose of this module:
      74             :     // This module provides the techniques and back up procedures for producing a triangulated
      75             :     // polygon from a >4 sided figure.  It is only used for DXF output.
      76             : 
      77             :     // Methodology employed:
      78             :     // Ear clipping has turned out to be the simplest, most robust technique.
      79             : 
      80           0 :     bool InPolygon(Vector const &point, Array1D<Vector> &poly, int const nsides)
      81             :     {
      82             :         // this routine is not used in the current scheme
      83             : 
      84             :         // Return value
      85             :         bool InPolygon;
      86             : 
      87             :         // Argument array dimensioning
      88           0 :         EP_SIZE_CHECK(poly, nsides);
      89             : 
      90             :         // Locals
      91             :         //'Return TRUE if the point (xp,yp) lies inside the circumcircle
      92             :         //'made up by points (x1,y1) (x2,y2) (x3,y3)
      93             :         //'The circumcircle centre is returned in (xc,yc) and the radius r
      94             :         //'NOTE: A point on the edge is inside the circumcircle
      95             : 
      96           0 :         Real64 constexpr epsilon(0.0000001);
      97             :         Real64 anglesum;
      98             :         Real64 costheta;
      99             :         int vert;
     100             :         Real64 m1;
     101             :         Real64 m2;
     102             :         Real64 acosval;
     103             : 
     104             :         // Object Data
     105           0 :         Vector p1;
     106           0 :         Vector p2;
     107             : 
     108           0 :         InPolygon = false;
     109             : 
     110           0 :         anglesum = 0.0;
     111             : 
     112           0 :         for (vert = 1; vert <= nsides - 1; ++vert) {
     113             : 
     114           0 :             p1.x = poly(vert).x - point.x;
     115           0 :             p1.y = poly(vert).y - point.y;
     116           0 :             p1.z = poly(vert).z - point.z;
     117             : 
     118           0 :             p2.x = poly(vert + 1).x - point.x;
     119           0 :             p2.y = poly(vert + 1).y - point.y;
     120           0 :             p2.z = poly(vert + 1).z - point.z;
     121             : 
     122           0 :             m1 = Modulus(p1);
     123           0 :             m2 = Modulus(p2);
     124             : 
     125           0 :             if (m1 * m2 <= epsilon) {
     126           0 :                 InPolygon = true;
     127           0 :                 break;
     128             :             } else {
     129           0 :                 costheta = (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z) / (m1 * m2);
     130           0 :                 acosval = std::acos(costheta);
     131           0 :                 anglesum += acosval;
     132             :             }
     133             :         }
     134             : 
     135           0 :         if (std::abs(anglesum - DataGlobalConstants::TwoPi) <= epsilon) {
     136           0 :             InPolygon = true;
     137             :         }
     138             : 
     139           0 :         return InPolygon;
     140             :     }
     141             : 
     142           0 :     Real64 Modulus(Vector const &point)
     143             :     {
     144             :         // this routine is not used in the current scheme
     145             : 
     146             :         // Return value
     147             :         Real64 rModulus;
     148             : 
     149           0 :         rModulus = std::sqrt(point.x * point.x + point.y * point.y + point.z * point.z);
     150             : 
     151           0 :         return rModulus;
     152             :     }
     153             : 
     154         142 :     int Triangulate(EnergyPlusData &state,
     155             :                     int const nsides, // number of sides to polygon
     156             :                     Array1D<Vector> &polygon,
     157             :                     Array1D<dTriangle> &outtriangles,
     158             :                     Real64 const surfazimuth,            // surface azimuth angle (outward facing normal)
     159             :                     Real64 const surftilt,               // surface tilt angle
     160             :                     std::string const &surfname,         // surface name (for error messages)
     161             :                     DataSurfaces::SurfaceClass surfclass // surface class
     162             :     )
     163             :     {
     164             : 
     165             :         // Subroutine information:
     166             :         //       Author         Linda Lawrie
     167             :         //       Date written   October 2005
     168             :         //       Modified       na
     169             :         //       Re-engineered  na
     170             : 
     171             :         // Purpose of this subroutine:
     172             :         // This routine is a self-contained triangulation calculation from a polygon
     173             :         // of 3D vertices, nsides, to a returned set (as possible) of triangles -- noted
     174             :         // by vertex numbers.
     175             : 
     176             :         // Using/Aliasing
     177             :         using DataSurfaces::cSurfaceClass;
     178             :         using DataSurfaces::SurfaceClass;
     179             : 
     180             :         // Return value
     181             :         int Triangulate;
     182             : 
     183             :         // Argument array dimensioning
     184         142 :         EP_SIZE_CHECK(polygon, nsides);
     185             : 
     186             :         // Subroutine parameter definitions:
     187         142 :         Real64 constexpr point_tolerance(0.00001);
     188             : 
     189             :         // Subroutine local variable declarations:
     190             :         bool errFlag;
     191         284 :         Array1D_int ears(nsides);
     192         284 :         Array1D_int r_angles(nsides);
     193         284 :         Array1D<Real64> rangles(nsides);
     194         284 :         Array1D_int c_vertices(nsides);
     195         284 :         Array2D_int earvert(nsides, 3);
     196         284 :         Array1D_bool removed(nsides);
     197         284 :         Array1D_int earverts(3);
     198         284 :         Array1D<Real64> xvt(nsides);
     199         284 :         Array1D<Real64> yvt(nsides);
     200         284 :         Array1D<Real64> zvt(nsides);
     201             : 
     202             :         int ntri;
     203             :         int nvertcur;
     204             :         int ncount;
     205             :         int svert;
     206             :         int mvert;
     207             :         int evert;
     208             :         int nears;
     209             :         int nrangles;
     210             :         int ncverts;
     211         284 :         std::string line;
     212             : 
     213             :         // Object Data
     214         284 :         Array1D<Vector_2d> vertex(nsides);
     215         284 :         Array1D<dTriangle> Triangle(nsides);
     216             : 
     217         142 :         errFlag = false;
     218             :         //  vertex=polygon
     219             :         //  if (surfname == 'BOTTOM:OFFICE_E_3') THEN
     220             :         //    trackit=.TRUE.
     221             :         //  else
     222             :         //    trackit=.FALSE.
     223             :         //  endif
     224         284 :         if (surfclass == SurfaceClass::Floor || surfclass == SurfaceClass::Roof || surfclass == SurfaceClass::Overhang) {
     225         142 :             CalcRfFlrCoordinateTransformation(nsides, polygon, surfazimuth, surftilt, xvt, yvt, zvt);
     226        1270 :             for (svert = 1; svert <= nsides; ++svert) {
     227        5272 :                 for (mvert = svert + 1; mvert <= nsides; ++mvert) {
     228        4144 :                     if (std::abs(xvt(svert) - xvt(mvert)) <= point_tolerance) xvt(svert) = xvt(mvert);
     229        4144 :                     if (std::abs(zvt(svert) - zvt(mvert)) <= point_tolerance) zvt(svert) = zvt(mvert);
     230             :                 }
     231             :             }
     232        1270 :             for (svert = 1; svert <= nsides; ++svert) {
     233        1128 :                 vertex(svert).x = xvt(svert);
     234        1128 :                 vertex(svert).y = zvt(svert);
     235             :                 //      if (trackit) write(outputfiledebug,*) 'x=',xvt(svert),' y=',zvt(svert)
     236             :             }
     237             :         } else {
     238           0 :             CalcWallCoordinateTransformation(nsides, polygon, surfazimuth, surftilt, xvt, yvt, zvt);
     239           0 :             for (svert = 1; svert <= nsides; ++svert) {
     240           0 :                 for (mvert = svert + 1; mvert <= nsides; ++mvert) {
     241           0 :                     if (std::abs(xvt(svert) - xvt(mvert)) <= point_tolerance) xvt(svert) = xvt(mvert);
     242           0 :                     if (std::abs(zvt(svert) - zvt(mvert)) <= point_tolerance) zvt(svert) = zvt(mvert);
     243             :                 }
     244             :             }
     245           0 :             for (svert = 1; svert <= nsides; ++svert) {
     246           0 :                 vertex(svert).x = xvt(svert);
     247           0 :                 vertex(svert).y = zvt(svert);
     248             :             }
     249             :         }
     250             : 
     251             :         // find ears
     252         142 :         nvertcur = nsides;
     253         142 :         ncount = 0;
     254         142 :         svert = 1;
     255         142 :         mvert = 2;
     256         142 :         evert = 3;
     257         142 :         removed = false;
     258        1544 :         while (nvertcur > 3) {
     259         702 :             generate_ears(state, nsides, vertex, ears, nears, r_angles, nrangles, c_vertices, ncverts, removed, earverts, rangles);
     260         702 :             if (!any_gt(ears, 0)) {
     261           3 :                 ShowWarningError(state,
     262           2 :                                  "DXFOut: Could not triangulate surface=\"" + surfname + "\", type=\"" + cSurfaceClass(surfclass) +
     263             :                                      "\", check surface vertex order(entry)");
     264           1 :                 ++state.dataDXFEarClipping->errcount;
     265           1 :                 if (state.dataDXFEarClipping->errcount == 1 && !state.dataGlobal->DisplayExtraWarnings) {
     266           1 :                     ShowContinueError(state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on individual surfaces.");
     267             :                 }
     268           1 :                 if (state.dataGlobal->DisplayExtraWarnings) {
     269           0 :                     ShowMessage(state, format(" surface={} class={}", surfname, cSurfaceClass(surfclass)));
     270             : 
     271           0 :                     for (int j = 1; j <= nsides; ++j) {
     272           0 :                         ShowMessage(state, format(" side={} ({:.1R},{:.1R},{:.1R})", j, polygon(j).x, polygon(j).y, polygon(j).z));
     273             :                     }
     274           0 :                     ShowMessage(state, format(" number of triangles found={:12}", ncount));
     275           0 :                     for (int j = 1; j <= nrangles; ++j) {
     276           0 :                         ShowMessage(state, format(" r angle={} vert={} deg={:.1R}", j, r_angles(j), rangles(j) * DataGlobalConstants::RadToDeg));
     277             :                     }
     278             :                 }
     279           1 :                 break; // while loop
     280             :             }
     281         701 :             if (nears > 0) {
     282         701 :                 svert = earverts(1);
     283         701 :                 mvert = earverts(2);
     284         701 :                 evert = earverts(3);
     285             :                 // remove ear
     286         701 :                 ++ncount;
     287         701 :                 removed(mvert) = true;
     288         701 :                 earvert(ncount, 1) = svert;
     289         701 :                 earvert(ncount, 2) = mvert;
     290         701 :                 earvert(ncount, 3) = evert;
     291         701 :                 --nvertcur;
     292             :             }
     293         701 :             if (nvertcur == 3) {
     294         141 :                 int j = 1;
     295         141 :                 ++ncount;
     296        1261 :                 for (int i = 1; i <= nsides; ++i) {
     297        1120 :                     if (removed(i)) continue;
     298         423 :                     earvert(ncount, j) = i;
     299         423 :                     ++j;
     300             :                 }
     301             :             }
     302             :         }
     303             : 
     304         142 :         ntri = ncount;
     305             : 
     306         984 :         for (int i = 1; i <= ntri; ++i) {
     307         842 :             Triangle(i).vv0 = earvert(i, 1);
     308         842 :             Triangle(i).vv1 = earvert(i, 2);
     309         842 :             Triangle(i).vv2 = earvert(i, 3);
     310             :         }
     311             : 
     312         142 :         outtriangles.allocate(ntri);
     313         984 :         for (int i = 1; i <= ntri; ++i) {
     314         842 :             outtriangles(i) = Triangle(i);
     315             :         }
     316             : 
     317         142 :         Triangulate = ntri;
     318             : 
     319         284 :         return Triangulate;
     320             :     }
     321             : 
     322        4420 :     Real64 angle_2dvector(Real64 const xa, // vertex coordinate
     323             :                           Real64 const ya, // vertex coordinate
     324             :                           Real64 const xb, // vertex coordinate
     325             :                           Real64 const yb, // vertex coordinate
     326             :                           Real64 const xc, // vertex coordinate
     327             :                           Real64 const yc  // vertex coordinate
     328             :     )
     329             :     {
     330             : 
     331             :         // Function information:
     332             :         //       Author         Linda Lawrie
     333             :         //       Date written   October 2005
     334             :         //       Modified       na
     335             :         //       Re-engineered  na
     336             : 
     337             :         // Purpose of this function:
     338             :         // This function calculates the angle between two sides of a 2d polygon.
     339             :         // It computes the interior angle in radians at vertex
     340             :         // (XB,YB) of the chain formed by the directed edges from
     341             :         // (XA,YA) to (XB,YB) to (XC,YC).  The interior is to the
     342             :         // left of the two directed edges.
     343             : 
     344             :         // References:
     345             :         // Geometry Tools for Computer Graphics
     346             : 
     347             :         // Return value
     348             :         Real64 angle; // the angle, between 0 and 2*PI.
     349             : 
     350             :         // Locals
     351             :         // Function argument definitions:
     352             :         // angle is set to PI/2 in the degenerate case.
     353             : 
     354             :         // Function parameter definitions:
     355        4420 :         Real64 constexpr epsilon(0.0000001);
     356             : 
     357             :         // Function local variable declarations:
     358             :         Real64 t;
     359             :         Real64 x1;
     360             :         Real64 x2;
     361             :         Real64 y1;
     362             :         Real64 y2;
     363             : 
     364        4420 :         x1 = xa - xb;
     365        4420 :         y1 = ya - yb;
     366        4420 :         x2 = xc - xb;
     367        4420 :         y2 = yc - yb;
     368             : 
     369        4420 :         t = std::sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2));
     370        4420 :         if (t == 0.0E+00) t = 1.0E+00;
     371             : 
     372        4420 :         t = (x1 * x2 + y1 * y2) / t;
     373             : 
     374        4420 :         if ((1.0E+00 - epsilon) < std::abs(t)) {
     375          81 :             t = sign(1.0E+00, t);
     376             :         }
     377             : 
     378        4420 :         angle = std::acos(t);
     379             : 
     380        4420 :         if (x2 * y1 - y2 * x1 < 0.0E+00) {
     381        1102 :             angle = 2.0E+00 * DataGlobalConstants::Pi - angle;
     382             :         }
     383             : 
     384        4420 :         return angle;
     385             :     }
     386             : 
     387       12980 :     bool polygon_contains_point_2d(int const nsides,            // number of sides (vertices)
     388             :                                    Array1D<Vector_2d> &polygon, // points of polygon
     389             :                                    Vector_2d const &point       // point to be tested
     390             :     )
     391             :     {
     392             : 
     393             :         // Function information:
     394             :         //       Author         Linda Lawrie
     395             :         //       Date written   October 2005
     396             :         //       Modified       na
     397             :         //       Re-engineered  na
     398             : 
     399             :         // Purpose of this function:
     400             :         // Determine if a point is inside a simple 2d polygon.  For a simple polygon (one whose
     401             :         // boundary never crosses itself).  The polygon does not need to be convex.
     402             : 
     403             :         // Methodology employed:
     404             :         // <Description>
     405             : 
     406             :         // References:
     407             :         // M Shimrat, Position of Point Relative to Polygon, ACM Algorithm 112,
     408             :         // Communications of the ACM, Volume 5, Number 8, page 434, August 1962.
     409             : 
     410             :         // Return value
     411             :         bool inside; // return value, true=inside, false = not inside
     412             : 
     413             :         // Argument array dimensioning
     414       12980 :         EP_SIZE_CHECK(polygon, nsides);
     415             : 
     416             :         // Function local variable declarations:
     417             :         int i;
     418             :         int ip1;
     419             : 
     420       12980 :         inside = false;
     421             : 
     422       51920 :         for (i = 1; i <= nsides; ++i) {
     423             : 
     424       38940 :             if (i < nsides) {
     425       25960 :                 ip1 = i + 1;
     426             :             } else {
     427       12980 :                 ip1 = 1;
     428             :             }
     429             : 
     430       38940 :             if ((polygon(i).y < point.y && point.y <= polygon(ip1).y) || (point.y <= polygon(i).y && polygon(ip1).y < point.y)) {
     431        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) {
     432        4423 :                     inside = !inside;
     433             :                 }
     434             :             }
     435             :         }
     436             : 
     437       12980 :         return inside;
     438             :     }
     439             : 
     440         702 :     void generate_ears(EnergyPlusData &state,
     441             :                        int const nvert, // number of vertices in polygon
     442             :                        Array1D<Vector_2d> &vertex,
     443             :                        Array1D_int &ears,       // number of ears possible (dimensioned to nvert)
     444             :                        int &nears,              // number of ears found
     445             :                        Array1D_int &r_vertices, // number of reflex vertices (>180) possible
     446             :                        int &nrverts,            // number of reflex vertices found (>=180)
     447             :                        Array1D_int &c_vertices, // number of convex vertices
     448             :                        int &ncverts,            // number of convex vertices found (< 180)
     449             :                        Array1D_bool &removed,   // array that shows if a vertex has been removed (calling routine)
     450             :                        Array1D_int &earvert,    // vertex indicators for first ear
     451             :                        Array1D<Real64> &rangles)
     452             :     {
     453             : 
     454             :         // Subroutine information:
     455             :         //       Author         Linda Lawrie
     456             :         //       Date written   October 2005
     457             :         //       Modified       na
     458             :         //       Re-engineered  na
     459             : 
     460             :         // Purpose of this subroutine:
     461             :         // This routine generates "ears", "reflex angles" and "convex angles" of the polygon
     462             :         // based on the method set for in the reference.
     463             : 
     464             :         // Methodology employed:
     465             :         // No elegance used here.  Always starts with first vertex in polygon.
     466             : 
     467             :         // References:
     468             :         // Geometric Tools for Computer Graphics, Philip Schneider, David Eberly. 2003.  Ear
     469             :         // clipping for triangulation is described in Chapter 13 on Polygon Partitioning.  Also
     470             :         // described in a small article "Triangulation by Ear Clipping", David Eberly, http://www.geometrictools.com
     471             : 
     472             :         // Argument array dimensioning
     473         702 :         EP_SIZE_CHECK(vertex, nvert);
     474         702 :         EP_SIZE_CHECK(ears, nvert);
     475         702 :         EP_SIZE_CHECK(r_vertices, nvert);
     476         702 :         EP_SIZE_CHECK(c_vertices, nvert);
     477         702 :         EP_SIZE_CHECK(removed, nvert);
     478         702 :         EP_SIZE_CHECK(earvert, 3);
     479         702 :         EP_SIZE_CHECK(rangles, nvert);
     480             : 
     481             :         // Subroutine local variable declarations:
     482             :         int svert;   // starting vertex
     483             :         int mvert;   // "middle" vertex (this will be an ear, if calculated)
     484             :         int evert;   // ending vertex
     485             :         Real64 ang;  // ang between
     486             :         int tvert;   // test vertex, intermediate use
     487             :         bool inpoly; // in polygon or not
     488             :         int j;       // loop counter
     489             : 
     490             :         // Object Data
     491        1404 :         Vector_2d point;               // structure for point
     492        1404 :         Array1D<Vector_2d> testtri(3); // structure for triangle
     493             : 
     494             :         // initialize, always recalculate
     495         702 :         ears = 0;
     496         702 :         r_vertices = 0;
     497         702 :         rangles = 0.0;
     498         702 :         nears = 0;
     499         702 :         nrverts = 0;
     500         702 :         c_vertices = 0;
     501         702 :         ncverts = 0;
     502             : 
     503        6734 :         for (svert = 1; svert <= nvert; ++svert) {
     504        6032 :             if (removed(svert)) continue;
     505             :             //  have starting vertex.  now need middle and end
     506        4420 :             mvert = svert + 1;
     507        6032 :             for (j = 1; j <= nvert; ++j) {
     508        6032 :                 if (mvert > nvert) mvert = 1;
     509        6032 :                 if (removed(mvert)) {
     510        1612 :                     ++mvert;
     511        1612 :                     if (mvert > nvert) mvert = 1;
     512             :                 } else {
     513        4420 :                     break;
     514             :                 }
     515             :             }
     516        4420 :             evert = mvert + 1;
     517        6032 :             for (j = 1; j <= nvert; ++j) {
     518        6032 :                 if (evert > nvert) evert = 1;
     519        6032 :                 if (removed(evert)) {
     520        1612 :                     ++evert;
     521        1612 :                     if (evert > nvert) evert = 1;
     522             :                 } else {
     523        4420 :                     break;
     524             :                 }
     525             :             }
     526             : 
     527             :             // have gotten start, middle and ending vertices.  test for reflex angle
     528             : 
     529        4420 :             ang = angle_2dvector(vertex(svert).x, vertex(svert).y, vertex(mvert).x, vertex(mvert).y, vertex(evert).x, vertex(evert).y);
     530             : 
     531        5521 :             if (ang > DataGlobalConstants::Pi) { // sufficiently close to 180 degrees.
     532        1101 :                 ++nrverts;
     533        1101 :                 r_vertices(nrverts) = mvert;
     534        1101 :                 rangles(nrverts) = ang;
     535        1101 :                 continue;
     536             :             } else {
     537        3319 :                 ++ncverts;
     538        3319 :                 c_vertices(ncverts) = mvert;
     539             :             }
     540             : 
     541             :             // convex angle, see if it's an ear
     542        3319 :             testtri(1) = vertex(svert);
     543        3319 :             testtri(2) = vertex(mvert);
     544        3319 :             testtri(3) = vertex(evert);
     545        3319 :             tvert = evert;
     546       19878 :             for (j = 4; j <= nvert; ++j) {
     547       17286 :                 ++tvert;
     548       17286 :                 if (tvert > nvert) tvert = 1;
     549       17286 :                 if (removed(tvert)) continue;
     550       12980 :                 point = vertex(tvert);
     551       12980 :                 inpoly = polygon_contains_point_2d(3, testtri, point);
     552       12980 :                 if (!inpoly) continue;
     553         727 :                 break;
     554             :             }
     555             :             //    if (trackit) then
     556             :             //      write(outputfiledebug,*) ' triangle=',svert,mvert,evert
     557             :             //      write(outputfiledebug,*) ' vertex1=',vertex(svert)%x,vertex(svert)%y
     558             :             //      write(outputfiledebug,*) ' vertex2=',vertex(mvert)%x,vertex(mvert)%y
     559             :             //      write(outputfiledebug,*) ' vertex3=',vertex(evert)%x,vertex(evert)%y
     560             :             //      write(outputfiledebug,*) ' inpoly=',inpoly
     561             :             //    endif
     562        3319 :             if (!inpoly) {
     563             :                 // found an ear
     564        2592 :                 ++nears;
     565        2592 :                 ears(nears) = mvert;
     566        2592 :                 if (nears == 1) {
     567         701 :                     earvert(1) = svert;
     568         701 :                     earvert(2) = mvert;
     569         701 :                     earvert(3) = evert;
     570             :                 }
     571        2592 :                 if (state.dataDXFEarClipping->trackit) {
     572           0 :                     print(state.files.debug, "ear={} triangle={:12}{:12}{:12}\n", nears, svert, mvert, evert);
     573             :                 }
     574             :             }
     575             :         }
     576         702 :     }
     577             : 
     578           0 :     void CalcWallCoordinateTransformation(int const nsides,
     579             :                                           Array1D<Vector> &polygon,
     580             :                                           Real64 const surfazimuth,
     581             :                                           [[maybe_unused]] Real64 const surftilt, // unused1208
     582             :                                           Array1D<Real64> &xvt,
     583             :                                           Array1D<Real64> &yvt,
     584             :                                           Array1D<Real64> &zvt)
     585             :     {
     586             : 
     587             :         // Subroutine information:
     588             :         //       Author         Linda Lawrie
     589             :         //       Date written   October 2005
     590             :         //       Modified       na
     591             :         //       Re-engineered  na
     592             : 
     593             :         // Purpose of this subroutine:
     594             :         // This routine transforms a "wall" (normally vertical polygon) to a south facing (180 deg outward
     595             :         // normal) polygon in 2 d (y vertices are then ignored).
     596             : 
     597             :         // Methodology employed:
     598             :         // Standard angle rotation
     599             : 
     600             :         // Argument array dimensioning
     601           0 :         EP_SIZE_CHECK(polygon, nsides);
     602           0 :         EP_SIZE_CHECK(xvt, nsides);
     603           0 :         EP_SIZE_CHECK(yvt, nsides);
     604           0 :         EP_SIZE_CHECK(zvt, nsides);
     605             : 
     606             :         // Subroutine local variable declarations:
     607             : 
     608             :         // convert surface (wall) to facing 180 (outward normal)
     609             : 
     610           0 :         Real64 const alpha = surfazimuth;
     611             : 
     612           0 :         Real64 const alpha180 = 180.0 - alpha; // amount to rotate
     613           0 :         Real64 const alphrad = alpha180 / DataGlobalConstants::RadToDeg;
     614           0 :         Real64 const cos_alphrad = std::cos(alphrad);
     615           0 :         Real64 const sin_alphrad = std::sin(alphrad);
     616             : 
     617           0 :         for (int i = 1; i <= nsides; ++i) {
     618           0 :             xvt(i) = cos_alphrad * polygon(i).x + sin_alphrad * polygon(i).y;
     619           0 :             yvt(i) = -sin_alphrad * polygon(i).x + cos_alphrad * polygon(i).y;
     620           0 :             zvt(i) = polygon(i).z;
     621             :         }
     622           0 :     }
     623             : 
     624         142 :     void CalcRfFlrCoordinateTransformation(int const nsides,
     625             :                                            Array1D<Vector> &polygon,
     626             :                                            [[maybe_unused]] Real64 const surfazimuth, // unused1208
     627             :                                            Real64 const surftilt,
     628             :                                            Array1D<Real64> &xvt,
     629             :                                            Array1D<Real64> &yvt,
     630             :                                            Array1D<Real64> &zvt)
     631             :     {
     632             : 
     633             :         // Subroutine information:
     634             :         //       Author         Linda Lawrie
     635             :         //       Date written   October 2005
     636             :         //       Modified       na
     637             :         //       Re-engineered  na
     638             : 
     639             :         // Purpose of this subroutine:
     640             :         // This routine transforms a roof/floor (normally flat polygon) to a flat
     641             :         // polygon in 2 d (z vertices are then ignored).
     642             : 
     643             :         // Methodology employed:
     644             :         // Standard angle rotation
     645             : 
     646             :         // Argument array dimensioning
     647         142 :         EP_SIZE_CHECK(polygon, nsides);
     648         142 :         EP_SIZE_CHECK(xvt, nsides);
     649         142 :         EP_SIZE_CHECK(yvt, nsides);
     650         142 :         EP_SIZE_CHECK(zvt, nsides);
     651             : 
     652             :         // Subroutine local variable declarations:
     653             : 
     654         142 :         Real64 const alpha = -surftilt;
     655         142 :         Real64 const alphrad = alpha / DataGlobalConstants::RadToDeg;
     656         142 :         Real64 const cos_alphrad = std::cos(alphrad);
     657         142 :         Real64 const sin_alphrad = std::sin(alphrad);
     658             : 
     659        1270 :         for (int i = 1; i <= nsides; ++i) {
     660        1128 :             xvt(i) = polygon(i).x;
     661        1128 :             yvt(i) = cos_alphrad * polygon(i).x + sin_alphrad * polygon(i).y;
     662        1128 :             zvt(i) = -sin_alphrad * polygon(i).x + cos_alphrad * polygon(i).y;
     663             :         }
     664         142 :     }
     665             : 
     666           0 :     void reorder([[maybe_unused]] int &nvert) // unused1208
     667             :     {
     668             : 
     669             :         // Locals
     670             :         // type (Vector_2d) nvertex(nvert)
     671             :         // integer i
     672             :         // type (Vector_2d) point
     673             :         // integer nrep
     674             : 
     675             :         //  Vertex, nverts is in cw order, reorder for calc
     676             : 
     677             :         // nrep=1
     678             :         // nvertex(1)=vertex(1)
     679             :         // do i=nvert,1,-1
     680             :         //  nvertex(nrep)=vertex(i)
     681             :         //  nrep=nrep+1
     682             :         // enddo
     683             :         // do i=1,nvert
     684             :         //  vertex(i)=nvertex(i)
     685             :         // enddo
     686           0 :     }
     687             : 
     688             : } // namespace DXFEarClipping
     689             : 
     690        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13