OpenClonk
C4MapScriptAlgoPolygon Class Reference

#include <C4MapScript.h>

Inheritance diagram for C4MapScriptAlgoPolygon:
[legend]
Collaboration diagram for C4MapScriptAlgoPolygon:
[legend]

Public Member Functions

 C4MapScriptAlgoPolygon (const C4PropList *props)
 
bool operator() (int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const override
 

Protected Member Functions

bool GetXYProps (const C4PropList *props, C4PropertyName k, int32_t *out_xy, bool zero_defaults)
 

Detailed Description

Definition at line 138 of file C4MapScript.h.

Constructor & Destructor Documentation

◆ C4MapScriptAlgoPolygon()

C4MapScriptAlgoPolygon::C4MapScriptAlgoPolygon ( const C4PropList props)

Definition at line 139 of file C4MapScriptAlgo.cpp.

140 {
141  // Get MAPALGO_Polygon properties
142  C4Value vptx, vpty;
143  props->GetProperty(P_X, &vptx); props->GetProperty(P_Y, &vpty);
144  C4ValueArray *ptx = vptx.getArray(), *pty = vpty.getArray();
145  if (!ptx || !pty || ptx->GetSize() != pty->GetSize())
146  throw C4AulExecError(R"(C4MapScriptAlgoPolygon: Expected two equally sized int arrays in properties "X" and "Y".)");
147  poly.resize(ptx->GetSize());
148  for (int32_t i=0; i<ptx->GetSize(); ++i)
149  {
150  poly[i].x = ptx->GetItem(i).getInt();
151  poly[i].y = pty->GetItem(i).getInt();
152  }
153  wdt = props->GetPropertyInt(P_Wdt);
154  if (!wdt) wdt = 1;
155  empty = !!props->GetPropertyInt(P_Empty);
156  open = !!props->GetPropertyInt(P_Open);
157  if (open && !empty) throw C4AulExecError("C4MapScriptAlgoPolygon: Only empty polygons may be open.");
158 }
@ P_Wdt
@ P_Y
@ P_X
@ P_Open
@ P_Empty
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
Definition: C4PropList.cpp:855
bool GetProperty(C4PropertyName k, C4Value *pResult) const
Definition: C4PropList.h:105
const C4Value & GetItem(int32_t iElem) const
Definition: C4ValueArray.h:38
int32_t GetSize() const
Definition: C4ValueArray.h:36
C4ValueArray * getArray() const
Definition: C4Value.h:118
int32_t getInt() const
Definition: C4Value.h:112

References C4Value::getArray(), C4Value::getInt(), C4ValueArray::GetItem(), C4PropList::GetProperty(), C4PropList::GetPropertyInt(), C4ValueArray::GetSize(), P_Empty, P_Open, P_Wdt, P_X, and P_Y.

Here is the call graph for this function:

Member Function Documentation

◆ GetXYProps()

bool C4MapScriptAlgo::GetXYProps ( const C4PropList props,
C4PropertyName  k,
int32_t *  out_xy,
bool  zero_defaults 
)
protectedinherited

Definition at line 26 of file C4MapScriptAlgo.cpp.

27 {
28  // Evaluate property named "k" in proplist props to store two numbers in out_xy:
29  // If props->k is a single integer, fill both numbers in out_xy with it
30  // If props->k is an array, check that it contains two numbers and store them in out_xy
31  if (!props->HasProperty(&Strings.P[k]))
32  {
33  if (zero_defaults) out_xy[0] = out_xy[1] = 0;
34  return false;
35  }
36  C4Value val; C4ValueArray *arr;
37  props->GetProperty(k, &val);
38  if ((arr = val.getArray()))
39  {
40  if (arr->GetSize() != 2)
41  throw C4AulExecError(FormatString(R"(C4MapScriptAlgo: Expected either integer or array with two integer elements in property "%s".)", Strings.P[k].GetCStr()).getData());
42  out_xy[0] = arr->GetItem(0).getInt();
43  out_xy[1] = arr->GetItem(1).getInt();
44  }
45  else
46  {
47  out_xy[0] = out_xy[1] = val.getInt();
48  }
49  return true;
50 }
C4StringTable Strings
Definition: C4Globals.cpp:42
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
bool HasProperty(C4String *k) const
Definition: C4PropList.h:122
const char * GetCStr() const
Definition: C4StringTable.h:49
C4String P[P_LAST]
const char * getData() const
Definition: StdBuf.h:442

References FormatString(), C4Value::getArray(), C4String::GetCStr(), StdStrBuf::getData(), C4Value::getInt(), C4ValueArray::GetItem(), C4PropList::GetProperty(), C4ValueArray::GetSize(), C4PropList::HasProperty(), C4StringTable::P, and Strings.

Referenced by C4MapScriptAlgoBorder::C4MapScriptAlgoBorder(), and C4MapScriptAlgoTurbulence::C4MapScriptAlgoTurbulence().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator()()

bool C4MapScriptAlgoPolygon::operator() ( int32_t  x,
int32_t  y,
uint8_t &  fg,
uint8_t &  bg 
) const
overridevirtual

Implements C4MapScriptAlgo.

Definition at line 160 of file C4MapScriptAlgo.cpp.

161 {
162  // Evaluate MAPALGO_Polygon at x,y: Return 1 for pixels within the polygon or its borders, 0 otherwise
163  int32_t crossings = 0;
164  for (size_t i=0; i<poly.size(); ++i)
165  {
166  Pt pt1 = poly[i];
167  Pt pt2 = poly[(i+1)%poly.size()];
168  // check border line distance
169  int32_t pdx = pt2.x-pt1.x, pdy = pt2.y-pt1.y, dx = x-pt1.x, dy = y-pt1.y;
170  if (i!=poly.size()-1 || !open)
171  {
172  int64_t d = dx*pdy-dy*pdx;
173  int32_t lsq = (pdx*pdx+pdy*pdy);
174  if (d*d < wdt*wdt*lsq) // check distance perpendicular to line
175  {
176  if (Inside(dx*pdx+dy*pdy, 0, lsq)) // check if point lies within pt1 and pt2
177  return true; // x/y lies on this line
178  }
179  }
180  // check point distance
181  if (dx*dx+dy*dy < wdt*wdt) return true; // x/y lies close to edge point
182  // filling of polygon: point is contained if it crosses an off number of borders
183  if (!empty && (pt1.y<=y) != (pt2.y<=y)) // crossing vertically?
184  {
185  // does line pt1-pt2 intersect line (x,y)-(inf,y)?
186  crossings += (dx>dy*pdx/pdy);
187  }
188  }
189  // x/y lies inside polygon
190  return (crossings % 2)==1;
191 }
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:43

References Inside().

Here is the call graph for this function:

The documentation for this class was generated from the following files: