Hexagons, Rectangles and Triangles... Sampling Frameworks

Blog Post created by Dan_Patterson on Sep 9, 2016

N-gon Demo

Updated:  2018-08-24  Added Triangles and a better labelling system

Created a toolbox and script tool for ArcGIS PRO 2.2 on the Code Sharing site... Sampling Grid ....

Yes... 'Pointy' and 'Flat Head' now have a home as well as rectangular sampling grids.  I also added cell labelling, akin to how spreadsheet cells are labelled (A1, B1 etc)

: -------------

The Toolbox

For those interested in parameter setup for tools

: -------------

This post .... how to draw octagon or hexagon in ArcGIS desktop ?  lead me back to an original post dealing with producing sampling grids.Numpy Snippets # 3 ... Phish_Nyet ... creating sampling grids using numpy and arcpy   For completeness, here are further thoughts.

There are two implementations of n-gons...flat topped and pointy topped.  They only differ by the rotation angle relative to the X/Y axis.  In the case of a square, the rotation is 45°. And yes...even a circle in ArcMap is represented as a 360-sided n-gon so it does have a pointy and a flat top.

Once the seed shape is created, it can be placed around the centroid of known points by creating a polygon from the array outputs.  I normally use FeatureclassToNumPyArray and NumPyArrayToFeatureclass to perform the transition from points to array and back again.  In my previous blog, I exploited this to produce a sampling grid using rectangles and hexagons of know width, location and orientation for both the flat and pointy topped examples.

There is nothing stopping one from creating any geometric shape in any configuration using these simple principles.  All that needs to be determined is the angles needed to produce the n-gon.  For example, the only two lines that need to be changed are these to represent the polygon (n-gon) angles.  From there, the desired width is used to create the final seed which can then be shifted into the desired configuration/location using other code samples included in my previous blogs.

See the script with the toolbox on the download site for more complete code samples.

``"""hexagon_demo_shape.pyAuthor:  Dan.Patterson@carleton.caPurpose: create hexagon shapes in two forms, flat-topped and pointy-toppedResult:   Produce hexagon of desired width in X direction centered about   the origin (0,0)NOTES:   see full code for other implementations"""import numpy as npnp.set_printoptions(precision=4,threshold=10,edgeitems=5,linewidth=75,suppress=True)def hex_flat(size=1,cols=1,rows=1):    """generate the points for the flat-headed hexagon """    f_rad = np.deg2rad([180.,120.,60.,0.,-60.,-120.,-180.])    X = np.cos(f_rad)*size;  Y = np.sin(f_rad)*size # scaled hexagon about 0,0    seed = np.array(zip(X,Y))            # array of coordinates    return seeddef hex_pointy(size=1,cols=1,rows=1):    """pointy hex angles, convert to sin,cos, zip and send"""    p_rad = np.deg2rad([150.,90,30.,-30.,-90.,-150.,150.])     X = np.cos(p_rad)*size;  Y = np.sin(p_rad)*size # scaled hexagon about 0,0    seed = np.array(zip(X,Y))    return seedif __name__ == '__main__':    flat = hex_flat(700,1,1)    pointy = hex_pointy(700,1,1)    print('\nFlat headed hexagon \n{}'.format(flat))    print('\nPointy headed hexagon \n{}'.format(pointy))``

Outputs for flat and pointy headed hexagons.

1 m width (unit width)100 Unit width700 m width

[[-1.     0.   ]

[-0.5    0.866]

[ 0.5    0.866]

[ 1.     0.   ]

[ 0.5   -0.866]

[-0.5   -0.866]

[-1.    -0.   ]]

[[-100.        0.    ]

[ -50.       86.6025]

[  50.       86.6025]

[ 100.        0.    ]

[  50.      -86.6025]

[ -50.      -86.6025]

[-100.       -0.    ]]

[[-700.        0.    ]

[-350.      606.2178]

[ 350.      606.2178]

[ 700.        0.    ]

[ 350.     -606.2178]

[-350.     -606.2178]

[-700.       -0.    ]]

[[-1.     0.   ]

[-0.5    0.866]

[ 0.5    0.866]

[ 1.     0.   ]

[ 0.5   -0.866]

[-0.5   -0.866]

[-1.    -0.   ]]

[[ -86.6025   50.    ]

[   0.      100.    ]

[  86.6025   50.    ]

[  86.6025  -50.    ]

[   0.     -100.    ]

[ -86.6025  -50.    ]

[ -86.6025   50.    ]]

[[-606.2178  350.    ]

[   0.      700.    ]

[ 606.2178  350.    ]

[ 606.2178 -350.    ]

[   0.     -700.    ]

[-606.2178 -350.    ]

[-606.2178  350.    ]]

Enjoy.  Should one require the rotation code or shape generation code, let me know or check the code for guidance in NumPy Snippets # 3