I know this is a long call since the subject is old but... I am trying to do something very similar and I'm wondering if you ever wrote that script and would like to share it? Was this work published?
Thanks in advance
Fun Python task! I think it should go something like this:
import random pa = 'protected_areas' # protected areas sr = arcpy.Describe(pa).spatialReference # spatial ref sa = 'study_area' # study area extent = arcpy.Describe(sa).extent # study area extent sa_geom = [row for row in arcpy.da.SearchCursor(sa,'SHAPE@',spatial_reference=sr)] # study area geometry new_polys =  # placeholder def rotate(poly,centroid): # magic function ang = random.random() * 2 * math.pi # random rotation angle in radians new_array = arcpy.Array() # placeholder rnd_x = random.uniform(extent.XMin,extent.XMax) # random x coordinate for new centroid rnd_y = random.uniform(extent.YMin,extent.YMax) # random y coordinate for new centroid rnd_centroid = arcpy.Point(rnd_x,rnd_y) # centroid point for part in poly: # for each polygon part for pnt in part: # for each vertex x_trans = pnt.X - centroid.X # normalize to zero y_trans = pnt.Y - centroid.Y # normalize to zero x_transprime = (math.cos(ang) * x_trans) - (math.sin(ang) * y_trans) # new x coord, from zero y_transprime = (math.sin(ang) * x_trans) + (math.cos(ang) * y_trans) # new y coord, from zero x_prime = x_transprime + rnd_centroid.X # move to new centroid x y_prime = y_transprime + rnd_centroid.Y # move to new centroid y new_array.add(arcpy.Point(x_prime, y_prime)) # add to array candidate_poly = arcpy.Polygon(new_array,sr) # make polygon from array for new_poly in new_polys: # compare to polygons already added to new_polys if not candidate_poly.disjoint(new_poly) or not sa_geom.contains(candidate_poly): # check if overlap with polygons and is fully inside study area candidate_poly = rotate(poly,centroid) # if the new polygon violates criteria, call function again return (candidate_poly) # return the final good polygon with arcpy.da.SearchCursor(pa,'SHAPE@',spatial_reference=sr) as cursor: # for each polygon for row in cursor: centroid = row.centroid # calculate centroid new_polys.append(rotate(row,centroid)) # add returned good polygon to list arcpy.CopyFeatures_management(new_polys,r'in_memory\new_polys') # write to disk
* rotation math from here: Rotating Features in ArcGIS for Desktop using ArcPy? - Geographic Information Systems Stack Exchange
So I think I understand your script and that kind of works thanks - but...
1. It looks like the small polygons (protected areas) need to be single part for it to work, even though it looks like the loop does look at multipart (?). I tried with sample data - did not work with multipart but worked fine with single.
2. My new random polygons always fall within the extent of the study area, but not always within the actual study area (which is a complex multipart polygon too). Although only using a large single part study area still did not work.
Note that I'm a Python newbie (but work well in R) so obvious things to you might not be obvious to me
I'll then have to loop that randomisation n times and calculate values based on intersection between new polygons and other layers for every randomisation... steep learning curve but will get there!