I have a question. I am trying to calculate the area of the following layer (see picture)
intersect area
I used the intersection tool to find the intersection between the layer of 4 overlapping buffers with another polygon (transformed from raster and therefore consists of many other polygons). This layers now consists of more than 200 polygons and most of them on top of each other. I actually want to calculate the 2D area of this layer, so I actually want to transform this layer of many polygons into one polygon so that you are able to calculate the area of this one polygon. My question is therefore, is there a possibility to transform this layer into polygons that are adjacent of each other and that there are no overlapping polygons anymore so I can calculate the area? Maybe there is another way to do this?
If understand your question correctly, you should be able to use the Dissolve Boundaries tool in ArcGIS; dissolve into one polygon; then calculate the area of that polygon.
I'm looking for an algorithm that can take an area containing a set of non-overlapping convex polygons as input, and break the space outside of the polygons into a set of non-overlapping convex quadrilaterals. The quadrilaterals need to have the property that they (individually) use as much horizontal space as possible.
Here's the input:
Here's the desired output:
I feel like I have seen some variation of this algorithm used to calculate regions to be flood-filled in very old paint programs. Is there a pleasant way to do this in better than O(n^2) time?
Edit: I realize there are some triangles in the output. I should probably state that quadrilaterals are the desired output, falling back to triangles only when it's physically impossible to use a quad.
I came up with a solution to this. In order to solve this efficiently, some sort of spatial data structure is needed in order to query which polygons are overlapped by a given rectangular area. I used a Quadtree. It's also necessary for the polygon data structure being used to be able to distinguish between internal and external edges. An edge is internal if it is common to two polygons.
The steps are as follows (assuming a coordinate system with the origin in the top-left corner):
Insert all polygons into whatever spatial data structure you're using.
Iterate over all polygons and build a list of all of the Y values upon
which vertices occur. This has the effect of conceptually dividing up
the scene into horizontal strips:
Iterate over the pairs of Y values from top to bottom. For each
pair (y0, y1) of Y values, declare a rectangular area a with
the the top left corner (0, y0) and bottom right corner
(width, y1). Determine the set of polygons S that are
overlapped by a by querying the spatial data structure. For
each polygon p in S, determine the set of edges E of p
that are overlapped by a. For best results, ignore any edge in
E with a normal that points directly up or down. For each
edge e in E, it's then necessary to determine the pair of
points at which e intersects the top and bottom edges of a.
This is achieved with a simple line intersection test,
treating the top and bottom edges of a as simple horizontal
line segments. Join the intersection points to create a set of
new line segments, shown in red:
Create vertical line segments L0 = (0, y0) → (0, y1) and
L1 = (width, y0) → (width, y1). Working from left to right,
gather any line segments created in the preceding step into pairs,
ignoring any line segments that were created from internal edges.
If there were no intersecting external edges, then the only two
edges will be L0 and L1. In this example strip, only four
edges remain:
Join the vertices in the remaining pairs of edges to create
polygons:
Repeating the above process for each horizontal strip achieves
the desired result. Assuming a set of convex, non-overlapping
polygons as input, the created polygons are guaranteed to be
either triangles or quadrilaterals. If a horizontal strip contains
no edges, the algorithm will create a single rectangle. If no
polygons exist in the scene, the algorithm will create a single
rectangle covering the whole scene.
i have a list of boundaries (polygons) and a list of ways all represented by latitudes and longitudes. i would like to find out if one way is inside a polygon.
i do this in perl but cant find anything useful to calculate. Math::Polygon (::Calc) has interesting functions, but not for lat/lon only for x/y.
So im thinking about making it easier and generating a bounding box of each polygon, so its easier for me to check if one point of a way is inside a bounding box.
Does anyone know how the algorithm looks like to get the bounding box. a pseudo code would be enough so i can code it in perl.
It would be even better to check for being inside a polygon without converting a polygon into a bounding box, but i wasnt able to find anything useful on the net. There are some for simple 2d x/y based coordinate systems, but not for spherical lat/lon.
First, place the start and end points of each of the polygon's line segments in an array. Then iterate over the array to find MinX, MinY, MaxX and MaxY. Then the point (MinX, MinY) is the lower left corner of your box, and (MaxX, MaxY) is the upper right corner.
I am currently getting the bounding box for my polygon by getting the min/max x and min/max y of the points, but when rotating the polygon the bounding box is too small to fit the rotated polygon. See the illustration for clarification:
This:
Turns into this:
How would I get the bounding box that is big enough to contain any rotated state?
If I understand the problem correctly, this is really trivial.
The point furthest away from the center will always be a vertex. So find the vertex with the maximum distance from the center, and make the box large enough to fit the polygon when that vertex is facing straight up, down, left and right:
Find the vertex furthest away from the center, and let d denote its distance from the center.
The polygon will always fit in the box 2d × 2d.
Given a list of points that form a simple 2d polygon oriented in 3d space and a normal for that polygon, what is a good way to determine which points are specific 'corner' points?
For example, which point is at the lower left, or the lower right, or the top most point? The polygon may be oriented in any 3d orientation, so I'm pretty sure I need to do something with the normal, but I'm having trouble getting the math right.
Thanks!
You would need more information in order to make that decision. A set of (co-planar) points and a normal is not enough to give you a concept of "lower left" or "top right" or any such relative identification.
Viewing the polygon from the direction of the normal (so that it appears as a simple 2D shape) is a good start, but that shape could be rotated to any arbitrary angle.
Is there some other information in the 3D world that you can use to obtain a coordinate-system reference?
What are you trying to accomplish by knowing the extreme corners of the shape?
Are you looking for a bounding box?
I'm not sure the normal has anything to do with what you are asking.
To get a Bounding box, keep 4 variables: MinX, MaxX, MinY, MaxY
Then loop through all of your points, checking the X values against MaxX and MinX, and your Y values against MaxY and MinY, updating them as needed.
When looping is complete, your box is defined as MinX,MinY as the upper left, MinX, MaxY as upper right, and so on...
Response to your comment:
If you want your box after a projection, what you need is to get the "transformed" points. Then apply bounding box loop as stated above.
Transformed usually implies 2D screen coordinates after a projection(scene render) but it could also mean the 2D points on any plane that you projected on to.
A possible algorithm would be
Find the normal, which you can do by using the cross product of vectors connecting two pairs of different corners
Create a transformation matrix to rotate the polygon so that it is planer in XY space (i.e. normal alligned along the Z axis)
Calculate the coordinates of the bounding box or whatever other definition of corners you are using (as the polygon is now aligned in 2D space this is a considerably simpler problem)
Apply the inverse of the transformation matrix used in step 2 to transform these coordinates back to 3D space.
I believe that your question requires some additional information - namely the coordinate system with respect to which any point could be considered "topmost", or "leftmost".
Don't forget that whilst the normal tells you which way the polygon is facing, it doesn't on its own tell you which way is "up". It's possible to rotate (or "roll") around the normal vector and still be facing in the same direction.
This is why most 3D rendering systems have a camera which contains not only a "view" vector, but also "up" and "right" vectors. Changes to the latter two achieve the effect of the camera "rolling" around the view vector.
Project it onto a plane and get the bounding box.
I have a silly idea, but at the risk of gaining a negative a point, I'll give it a try:
Get the minimum/maximum value from
each three-dimensional axis of each
point on your 2d polygon. A single pass with a loop/iterator over the list of values for every point will suffice, simply replacing the minimum and maximum values as you go. The end result is a list that has the "lowest" X, Y, Z coordinates and "highest" X, Y, Z coordinates.
Iterate through this list of min/max
values to create each point
("corner") of a "bounding box"
around the object. The result
should be a box that always contains
the object regardless of axis
examined or orientation (no point on
the polygon will ever exceed the
maximum or minimums you collect).
Then get the distance of each "2d
polygon" point to each corner
location on the "bounding box"; the
shorter the distance between points,
the "closer" it is to that "corner".
Far from optimal, certainly crummy, but certainly quick. You could probably post-capture this during the object's rotation, by simply looking for the min/max of each rotated x/y/z value, and retaining a list of those values ahead of time.
If you can assume that there is some constraints regarding the shapes, then you might be able to get away with knowing less information. For example, if your shape was the composition of a small square with a long thin triangle on one side (i.e. a simple symmetrical geometry), then you could compare the distance from each list point to the "center of mass." The largest distance would identify the tip of the cone, the second largest would be the two points farthest from the tip of the cone, etc... If there was some order to the list, like points are entered in counter clockwise order (about the normal), you could identify all the points. This sounds like a bit of computation, so it might be reasonable to try to include some extra info with your shapes, like the "center of mass" and a reference point that is located "up" above the COM (but not along the normal). This will give you an "up" vector that you can cross with the normal to define some body coordinates, for example. Also, the normal can be defined by an ordering of the point list. If you can't assume anything about the shapes (or even if the shapes were symmetrical, for example), then you will need more data. It depends on your constraints.
If you know that the polygon in 3D is "flat" you can use the normal to transform all 3D-points of the vertices to a 2D-representation (of the points with respect to the plan in which the polygon is located) - but this still leaves you with defining the origin of this coordinate-system (but this don't really matter for your problem) and with the orientation of at least one of the axes (if you want orthogonal axes you can still rotate them around your choosen origin) - and this is where the trouble starts.
I would recommend using the Y-axis of your 3D-coordinate system, project this on your plane and use the resulting direction as "up" - but then you are in trouble in case your plan is orthogonal to the Y-axis (now you might want to use the projected Z-Axis as "up").
The math is rather simple (you can use the inner product (a.k.a. scalar product) for projection to your plane and some matrix stuff to convert to the 2D-coordinate system - you can get all of it by googling for raytracer algorithms for polygons.