Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A new algorithm for polygon clipping in solar calculations for rectangular surfaces #7574

Merged
merged 11 commits into from
Feb 19, 2020
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
A new algorithm for polygon clipping in solar calculations for rectangular surfaces

================

**Xuan Luo, Jerome Wei, Tianzhen Hong**

**Lawrence Berkeley National Laboratory**

- October 21, 2019

## Justification for New Feature

There exists an extensive amount of literature on polygon clipping when constrained to rectangular surfaces. The current polygon clipping method implemented in EnergyPlus, using the *Sutherland-Hodgman* algorithm, is a performance hotspot. The method is generalized for clipping area of all shapes, but in EnergyPlus simulations runs, are often called with only rectangular surfaces.

We propose a negligible amount of code to check if the clipping surface is rectangular. And if so,
we redirect to a new method using the `Slater & Barsky` algorithm.


## Overview

To clip a polygon against a rectangular region, we can go segment by segment and clip each line individually, saving the unique points of intersection as we go. Then, we add the necessary corners of the clipping rectangle making sure that clockwise order is preserved.

The `Slater & Barsky` algorithm relies on converting the line segment to be clipped into a parametric equation. Below is the general form for the x- and y- components of a parametric line:

- <img src="https://latex.codecogs.com/svg.latex? x = x_0 + t \Delta x" />

- <img src="https://latex.codecogs.com/svg.latex? y = y_0 + t \Delta y" />

Letting our subject line be starting at (x_0, y_0) and ending at (x_1, x_1):

- <img src="https://latex.codecogs.com/svg.latex? \Delta x = x_1 - x_0" />

- <img src="https://latex.codecogs.com/svg.latex? \Delta y = y_1 - y_0" />

Distances from the endpoints to the edges of the clipping rectangle that collide with the line are used to obtain two values of *t* that parameterize the equation, representing the pair of new endpoints.

Once we have the two values of t, t_1 and t_2, we can calculate the clipped line endpoints (Note that t_2 > t_1).

- <img src="https://latex.codecogs.com/svg.latex? x'_1 = x_0 + t_1 \Delta x" />

- <img src="https://latex.codecogs.com/svg.latex? y'_1 = y_0 + t_1 \Delta y" />

- <img src="https://latex.codecogs.com/svg.latex? x'_2 = x_0 + t_2 \Delta x" />

- <img src="https://latex.codecogs.com/svg.latex? y'_2 = y_0 + t_2 \Delta y" />

The `Slater & Barsky` algorithm uses space subdivision to reduce the number of pre-emptive calculations. We break the plane into 9 parts, where region (4) is the clipping region.


| 6 | 7 | 8 |

| 3 | 4 | 5 |

| 0 | 1 | 2 |

With this method, calculating deltas and plugging in the final parametric equations can be skipped if the subject line obeys certain conditions. For example, if the line begins in region (0) and ends in region (6), then no new endpoints need to be calculated.

Below are performance results for the calls to the solar clipping function `CLIPPOLY` in EnergyPlus. We see that the method provided by Slater & Barsky 1994 has a 31% speedup over all rectangular inputs in the **SolarShadingTest.idf** test file. Note that this performance gain is limited to rectangular inputs, so an estimate of the performance gain to the existing algorithm overall then is a function of the percentage of calls which apply a rectangular window. For example, if 33% of the calls are rectangles then the overall speedup to `CLIPPOLY` would be diminished by a factor 0.33.

#### Best case taken from 5 trials (SolarShadingTest.idf)

| | Slater-Barsky 1994 |
|----------------------------|--------------------|
| Rectangular inputs | 31% speedup |
| Overall assuming 50% rects | 15% speedup |

#### Worst case taken from 5 trials (SolarShadingTest.idf)

| | Slater-Barsky 1994 |
|----------------------------|--------------------|
| Rectangular inputs | 23% speedup |
| Overall assuming 50% rects | 11% speedup |


## Approach ##

We propose to add a new key, `SlaterBarskyandSutherlHodgman`, to the existing `ShadowCalculation` object, `Polygon Clipping Algorithm` field, for global shadow calculation control:

ShadowCalculation,
\unique-object
\memo This object is used to control details of the solar, shading, and daylighting models
\extensible:1
...
A2 , \field Polygon Clipping Algorithm
\note Advanced Feature. Internal default is SutherlandHodgman
\note Refer to InputOutput Reference and Engineering Reference for more information
\type choice
\key ConvexWeilerAtherton
\key SutherlandHodgman
\key SlaterBarskyandSutherlHodgman
\default SutherlandHodgman

If `SlaterBarskyandSutherlHodgman` is chosen, the polygon clipping for rectangular surfaces will be calculated using the *Slater and Barsky* algorithm, while the rest adopts the default *Sutherl and Hodgman* algorithm.

## Testing/Validation/Data Sources ##

The current test file, "SolarShadingTest.idf", is used for performance and accuracy evaluation and validation.

## Input Output Reference Documentation ##

TBD

## Input Description ##

N/A

## Outputs Description ##

N/A

## Engineering Reference ##

TBD

## Example File and Transition Changes ##

An example file "SolarShadingTest-Slater-Barsky.idf" will be developed based on the existing test case for testing the new algorithm implementation.

No transition change is required.

## References ##

insert text



















Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ \subsection{Polygon Clipping Algorithms}\label{polygon-clipping-algorithms}
Convex Weiler - Atherton
\item
Sutherland -- Hodgman
\item
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved
Slater -- Barsky (for rectangular surfaces only)
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved
\end{itemize}

The original EnergyPlus method for polygon clipping is a special version of the Weiler-Atherton model (Weiler, Atherton, 1977). It was developed to be sufficiently general to clip concave polygons with holes. The implementation in the current version of EnergyPlus, however, does not support concave shadowing surfaces or holes. The relative computational complexity is preserved -- the algorithm is carried out in four steps. For example, if A and B are polygons (see Figure~\ref{fig:point-a-vertex-of-a-enclosed-by-b}).
Expand All @@ -291,6 +293,53 @@ \subsection{Polygon Clipping Algorithms}\label{polygon-clipping-algorithms}

The Sutherland-Hodgman algorithm (Sutherland, Hodgman, 1974) is less complex compared to the Weiler-Atherton method and is well-suited to clipping convex polygons. In actuality, only convex shading surfaces are currently supported by EnergyPlus. Let X be a polygon called the ``subject polygon'' (SP) and Y be a polygon called the ``clipping polygon'' (CP). The method performs the computation by iterating over the edges of the CP and removing points from the SP that fall in the clipping plane, i.e.~points that fall to the left of the edge of the CP. Intersections between the clip edge and the edges of the SP are added appropriately, and points falling outside of the clipping plane, i.e.~to the right of the edge of the CP, are added the output polygon as well. This resultant polygon is stored and the process is repeated for the rest of the clip edges in CP. The process is analogous to cutting off pieces of the SP one-by-one with respect to each edge of the CP. The result is ordered and identical to the polygon produced by the Weiler-Atherton method.

The Slater-Barsky algorithm can also be chosen for clipping surfaces which are rectangular. The algorithm further saves computational cost. It relies on converting the line segment to be clipped into a parametric equation. Below is the general form for the x- and y- components of a parametric line:
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved

\begin{equation}
x = x_0 + t \Delta x
\end{equation}

\begin{equation}
y = y_0 + t \Delta y
\end{equation}

Letting our subject line be starting at ($x_0$, $y_0$) and ending at ($x_1$, $x_1$):

\begin{equation}
\Delta x = x_1 - x_0
\end{equation}

\begin{equation}
\Delta y = y_1 - y_0
\end{equation}

Distances from the endpoints to the edges of the clipping rectangle that collide with the line are used to obtain two values of $t$ that parameterize the equation, representing the pair of new endpoints.

Once we have the two values of $t, t_1 and t_2$, we can calculate the clipped line endpoints (Note that $t_2 > t_1$).
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved

\begin{equation}
x'_1 = x_0 + t_1 \Delta x
\end{equation}
\begin{equation}
y'_1 = y_0 + t_1 \Delta y
\end{equation}
\begin{equation}
x'_2 = x_0 + t_2 \Delta x
\end{equation}
\begin{equation}
y'_2 = y_0 + t_2 \Delta y
\end{equation}

The "Slater \& Barsky" algorithm uses space subdivision to reduce the number of pre-emptive calculations. We break the plane into 9 parts, where region (4) is the clipping region.
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved

```
| 6 | 7 | 8 |
| 3 | 4 | 5 |
| 0 | 1 | 2 |
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is rendering all on one line in the pdf: “‘ | 6 | 7 | 8 | | 3 | 4 | 5 | | 0 | 1 | 2 | “‘
Looks like you were trying for format this as code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a line break instead.


With this method, calculating deltas and plugging in the final parametric equations can be skipped if the subject line obeys certain conditions. For example, if the line begins in region (0) and ends in region (6), then no new endpoints need to be calculated.

\subsection{Overlapping Shadows}\label{overlapping-shadows}

After transforming the shadows onto the plane of the receiving surface, the basic job of the shadow algorithm is to determine the area of the overlap between the polygons representing the shadows and the polygon representing the receiving surface. Concave surfaces are supported only for exterior wall heat transfer surfaces, when using SutherlandHodgman option. Concave shading devices are not supported by the this option. Neither concave shading devices nor concave exterior wall heat transfer surfaces are supported by the ConvexWeilerAtherton clipping routine.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ \subsubsection{Inputs}\label{inputs-10-019}

\paragraph{Field: Polygon Clipping Algorithm}\label{field-polygon-clipping-algorithm}

This is an advanced feature. Prior to V7, the internal polygon clipping method was a special case of the Weiler-Atherton method. Now, two options are available: \textbf{SutherlandHodgman} (default) and \textbf{ConvexWeilerAtherton}. Theoretically, Sutherland-Hodgman is a simpler algorithm but it works well in cases where receiving surfaces (of shadows) are non-convex. The Weiler-Atherton implementation is only accurate where both casting and receiving surfaces are convex. Warnings/severe errors are displayed when necessary. More details on polygon clipping are contained in the Engineering Reference.
This is an advanced feature. Prior to V7, the internal polygon clipping method was a special case of the Weiler-Atherton method. Now, three options are available: \textbf{SutherlandHodgman} (default), \textbf{SlaterBarskyandSutherlHodgman} and \textbf{ConvexWeilerAtherton}. Theoretically, Sutherland-Hodgman is a simpler algorithm but it works well in cases where receiving surfaces (of shadows) are non-convex. The Weiler-Atherton implementation is only accurate where both casting and receiving surfaces are convex. Warnings/severe errors are displayed when necessary. If `SlaterBarskyandSutherlHodgman` is chosen, the polygon clipping for rectangular surfaces will be calculated using the *Slater and Barsky* algorithm, while the rest adopts the default *Sutherl and Hodgman* algorithm. More details on polygon clipping are contained in the Engineering Reference.
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved

\paragraph{Field: Sky Diffuse Modeling Algorithm}\label{field-sky-diffuse-modeling-algorithm}

Expand Down
1 change: 1 addition & 0 deletions idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ ShadowCalculation,
\type choice
\key ConvexWeilerAtherton
\key SutherlandHodgman
\key SlaterBarskyandSutherlHodgman
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved
\default SutherlandHodgman
A3 , \field Sky Diffuse Modeling Algorithm
\note Advanced Feature. Internal default is SimpleSkyDiffuseModeling
Expand Down
3 changes: 3 additions & 0 deletions src/EnergyPlus/DataSystemVariables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ namespace DataSystemVariables {
std::string const cIgnoreBeamRadiation("IgnoreBeamRadiation");
std::string const cIgnoreDiffuseRadiation("IgnoreDiffuseRadiation");
std::string const cSutherlandHodgman("SutherlandHodgman");
std::string const cSlaterandBarsky("SlaterandBarsky");
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved
std::string const cMinimalSurfaceVariables("CreateMinimalSurfaceVariables");
std::string const cMinimalShadowing("MinimalShadowing");
std::string const cNumActiveSims("cntActv");
Expand Down Expand Up @@ -150,6 +151,7 @@ namespace DataSystemVariables {
bool DeveloperFlag(false); // TRUE if developer flag is turned on. (turns on more displays to console)
bool TimingFlag(false); // TRUE if timing flag is turned on. (turns on more timing displays to console)
bool SutherlandHodgman(true); // TRUE if SutherlandHodgman algorithm for polygon clipping is to be used.
bool SlaterandBarsky(false); // TRUE if SlaterandBarsky algorithm for polygon clipping is to be used for vertical polygons.
bool DetailedSkyDiffuseAlgorithm(false); // use detailed diffuse shading algorithm for sky (shading transmittance varies)
bool DetailedSolarTimestepIntegration(false); // when true, use detailed timestep integration for all solar,shading, etc.
bool TrackAirLoopEnvFlag(false); // If TRUE generates a file with runtime statistics for each HVAC
Expand Down Expand Up @@ -375,6 +377,7 @@ namespace DataSystemVariables {
DeveloperFlag = false;
TimingFlag = false;
SutherlandHodgman = true;
SlaterandBarsky = false;
DetailedSkyDiffuseAlgorithm = false;
DetailedSolarTimestepIntegration = false;
TrackAirLoopEnvFlag = false;
Expand Down
2 changes: 2 additions & 0 deletions src/EnergyPlus/DataSystemVariables.hh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace DataSystemVariables {
extern std::string const cIgnoreBeamRadiation;
extern std::string const cIgnoreDiffuseRadiation;
extern std::string const cSutherlandHodgman;
extern std::string const cSlaterandBarsky;
extern std::string const cMinimalSurfaceVariables;
extern std::string const cMinimalShadowing;
extern std::string const cNumActiveSims;
Expand Down Expand Up @@ -118,6 +119,7 @@ namespace DataSystemVariables {
extern bool DeveloperFlag; // TRUE if developer flag is turned on. (turns on more displays to console)
extern bool TimingFlag; // TRUE if timing flag is turned on. (turns on more timing displays to console)
extern bool SutherlandHodgman; // TRUE if SutherlandHodgman algorithm for polygon clipping is to be used.
extern bool SlaterandBarsky; // TRUE if SlaterandBarsky algorithm for polygon clipping is to be used for vertical polygons.
extern bool DetailedSkyDiffuseAlgorithm; // use detailed diffuse shading algorithm for sky (shading transmittance varies)
extern bool DetailedSolarTimestepIntegration; // when true, use detailed timestep integration for all solar,shading, etc.
extern bool TrackAirLoopEnvFlag; // If TRUE generates a file with runtime statistics for each HVAC
Expand Down
3 changes: 3 additions & 0 deletions src/EnergyPlus/EnergyPlusPgm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@ int RunEnergyPlus(std::string const & filepath)
get_environment_variable(cSutherlandHodgman, cEnvValue);
if (!cEnvValue.empty()) SutherlandHodgman = env_var_on(cEnvValue); // Yes or True

get_environment_variable(cSlaterandBarsky, cEnvValue);
if (!cEnvValue.empty()) SlaterandBarsky = env_var_on(cEnvValue); // Yes or True

get_environment_variable(cMinimalShadowing, cEnvValue);
if (!cEnvValue.empty()) lMinimalShadowing = env_var_on(cEnvValue); // Yes or True

Expand Down
6 changes: 5 additions & 1 deletion src/EnergyPlus/SimulationManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1765,7 +1765,11 @@ namespace SimulationManager {
ObjexxFCL::gio::write(EchoInputFile, fmtLD) << "NumReportList=" << NumReportList;
ObjexxFCL::gio::write(EchoInputFile, fmtLD) << "InstMeterCacheSize=" << InstMeterCacheSize;
if (SutherlandHodgman) {
ObjexxFCL::gio::write(EchoInputFile, fmtLD) << "ClippingAlgorithm=SutherlandHodgman";
if (SlaterandBarsky) {
ObjexxFCL::gio::write(EchoInputFile, fmtLD) << "ClippingAlgorithm=SlaterBarskyandSutherlHodgman";
xuanluo113 marked this conversation as resolved.
Show resolved Hide resolved
} else {
ObjexxFCL::gio::write(EchoInputFile, fmtLD) << "ClippingAlgorithm=SutherlandHodgman";
}
} else {
ObjexxFCL::gio::write(EchoInputFile, fmtLD) << "ClippingAlgorithm=ConvexWeilerAtherton";
}
Expand Down
Loading