Given some random w and h and 4 coordinates(x1, y1)...(x4, y4) check if x, y counters are inside those 4 coordinates.
I am trying to fill the space between those 4 coordinates, they will usually form a rectangle shape, but at different rotations.
At the moment I have a nested for loop to move over my "canvas", but I am failing to find a way to check if my counters are inside the coordinates.
I have looked at line drawing algorithms to build this, but so far no luck.
Can someone point me to some resources please.
To check if a point is inside a triangle, take the orientation
(y2 - y1)*(x3 - x2) - (y3 - y2)*(x2 - x1)
the sign is zero if the points are linear, otherwise it is negative for counter-clockwise and positive for clockwise. If orientation ABC, ABD, and ACD is the same, then A is in the triangle BCD.
So we can first check our convex hull which will either be a line, a triangle, or a quad. If it is a triangle, we can easily test for further points inside. It it is a convex quad, the test also works, but we have to add an extra point.
Related
I've been trying to figure out the best way to draw double border around an isosceles triangle in source code. I would like to draw something like the following:
I've tried two approaches neither of which work.
First the naive approach. Enlarge the bounding box and redraw the triangle inside the larger box. Problem is that the space between the two triangles is uneven. A bit of algebra shows why this is the case. See next image:
Scale the triangle relative to the center point. I do this by translating the 'center' of the triangle to the origin, scale and translate back. I compute the center using cx = (x1+x2+x3)/3, and cy = (y1+y2+y3)/3 (centroid center), and x and y are the coordinatess of the vertices. If I do this I get the following image which is obviously not right either.
Question. I think approach number two should work but I am using the right center when scaling?
The scaling center you should use is the Incenter and not the Centroid. You could find the incenter using the formula:
((a*x1+b*x2+c*x3)/(a+b+c), (a*y1+b*y2+c*y3)/(a+b+c))
where a is the length of the side opposite to the point (x1, y1), b - the opposite to (x2, y2) and c - (x3, y3).
Visual proof:
Notice that it is irrelevant whether the triangle is isosceles.
I'm making game in Unity. There's a rectangle intersected by a straight line. I need to find which part of rect is bigger and how much. Do anyone knows algorithm how to do this?
Rect and lines are set with points (4 for rect and 2 for lines)
The implicit equation of the line is
S(x,y) = (x - x0) (y1 - y0) - (y - y0) (x1 - x0) = 0
When you plug the coordinates of a corner, the sign of S(x, y) tells you on what side of the line you are. And better, if you evaluate Sa and Sb at two corners and they have different signs, the intersection is at a fraction Sa / (Sa - Sb) along the side ab.
Now, process all four edges in turn in clockwise order. For every edge, keep the starting corner if positive and keep the intersection if any. In the end, you'll get 0 to 5 points defining the convex polygon which is in the positive domain.
The area is found by the shoelace formula.
Determine if the shaded area is purely a triangle, if so, calculate the area of that triangle (a * b) / 2 , this would solve the right hand diagram.
For the left hand diagram, treat the area as a triangle and a rectangle. Compute the shaded area by adding together the triangles area and the rectangles area.
HTH
I need help creating a specialized line-collision algorithm that allows "cutting corners" at certain angles.
In the following pictures, let the blue square represent the player and the black square represent a wall. The white squares, then, represent squares in a player's "line of sight" (valid squares), and the grey squares are squares outside a player's "line of sight" (invalid squares):
The second image is where things get more interesting as we start cutting corners:
Let's take a closer look at this line which is allowed despite passing over the corner of the wall:
The line is allowed because:
dx <= 0.5 (with a square being 1x1)
dx/dy is above a certain ratio (say, 2 - I'm not sure of the exact value represented in these images.)
The converse line is not allowed because the ratio (of dy/dx in this case) is too low:
Or perhaps I should talk about the angle of entry vs exit from the square....
The main problem I'm having is that I can't figure out how to generalize a solution for vectors traveling at any angle between two points on the grid. I can't decide if I should use trigonometry or what. My closest solution so far has been to use the decimal parts of line interceptions with each square as the dx and dy's and check whether it's allowed based on the slope of the line and what quadrant it's in.
Can anyone help?
I've also looked at borrowing or starting from other line algorithms, but I haven't found anything too useful. Most of them that I've seen want a line from (x1, y1) to (x2, y2) to be the same as from (x2, y2) to (x1, y1) which makes this problem quite different.
I suggest using circles, they are quite optimal corner wise.
I assume that coordinates are taken at the center of each pixels.
The algorithm for knowing if (xo,yo) is hiding the view from (xa,ya) to (xb,yb) would then be:
compute (xc,yc) the nearest point to (xo,yo) on the line from (xa,ya) to (xb,yb)
compute distance d from (xo,yo) to (xc,yc)
if d < half a pixel, then the view is hidden
You can simplify first two stages by directly calculating the distance between point and line http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line and eventually compute squared distance if you want to avoid sqrt
I have an array of latitude/longitude coordinate pairs that represent a polygon. I'm trying to determine the total area within that polygon. How would I go about doing that in Ruby?
Here's an example array of the polygon:
[[37.7663613767094, -122.452969210084], [37.7674219449606, -122.444718340349], [37.7701838510542, -122.445330289514], [37.7709974013834, -122.439159589248], [37.7700761930893, -122.438861402472], [37.7703501163684, -122.436868738421], [37.7712650571321, -122.437078116573], [37.7736056746515, -122.437533130227], [37.7714671036087, -122.453964210266], [37.7663613767094, -122.452969210084]]
It probably doesn't matter that much on the language. You can make use of the formula mentioned in here for calculating the area of a polygon:
http://mathworld.wolfram.com/PolygonArea.html
Assuming your points are (x1, y1) (x2, y2) .. (xn, yn) and they enclose a small area:
Area = 0.5 * (x1 * y2 - x2 * y1 + x2 * y3 - x3 * y2 ..... + xn * y1 - x1 * yn)
Note: This won't work for larger areas, for which you need to use more complex method to calculate the area, which involves angular co-ordinates. But, this does the job for small areas, which can be assumed to be planar.
Edit:
To get area in sq miles, you can do the following, from there, convert to whatever units you want.
areaInSqMiles = Area * (60 * 60 * 1.15 * 1.15)
language independent solution:
GIVEN: a polygon can ALWAYS be composed by n-2 triangles that do not overlap (n = number of points OR sides). 1 triangle = 3 sided polygon = 1 triangle; 1 square = 4 sided polygon = 2 triangles; etc ad nauseam QED
therefore, a polygon can be reduced by "chopping off" triangles and the total area will be the sum of the areas of these triangles. try it with a piece of paper and scissors, it is best if you can visualize the process before following.
if you take any 3 consecutive points in a polygons path and create a triangle with these points, you will have one and only one of three possible scenarios:
resulting triangle is completely inside original polygon
resulting triangle is totally outside original polygon
resulting triangle is partially contained in original polygon
we are interested only in cases that fall in the first option (totally contained).
every time we find one of these, we chop it off, calculate its area (easy peasy, wont explain formula here) and make a new polygon with one less side (equivalent to polygon with this triangle chopped off). until we have only one triangle left.
how to implement this programatically:
create an array of points. run the array making triangles from points x, x+1 and x+2. transform each triangle from a shape to an area and intersect it with area created from polygon. IF the resulting intersection is identical to the original triangle, then said triangle is totally contained in polygon and can be chopped off. remove x+1 from the array and start again from x=0. otherwise, move to next point x+1 in array.
additionally if you are looking to integrate with mappping and are starting from geopoints, you must convert from geopoints to screenpoints. this requires deciding a modelling and formula for earths shape (though we tend to think of the earth as a sphere, it is actually an irregular ovoid (eggshape), with dents. there are many models out there, for further info wiki.
You can use this library which wraps GEOS (a C geospatial library itself a port of the JTS).
https://github.com/dark-panda/ffi-geos
This library can handle the calculations in coordinate space and takes care of the approximations.
Depending on how much accuracy you need I would project the data first to an appropriate projection (not Mercator). Then calculate your area
There is an awesome example on how to multiply verticies. Essentially exactly what you would like to do!!
http://www.wikihow.com/Calculate-the-Area-of-a-Polygon
Some techniques for this include integration (divide the polygon into latitudinal strips and integrate. You can also project onto a flat surface and calculate that area.
It does not need to be very accurate. Does anyone know a good way to do this?
any help is much appreciated.
When you say “it does not need to be very accurate” you don’t say how inaccurate a solution you’re prepared to accept. Also, you don’t say how big the geographic region under consideration is likely to be. These two criteria make a big difference to the kind of approach that needs to be taken.
With a small regions (a few kilometres, say), a flat approximation may be good enough (for example, the Mercator projection) and some of the other responses tell you how to do that. With larger regions you have to take the Earth’s sphericity into account. And if you want inaccuracy less than a percent or so, you need to take the eccentricity of Earth into account.
I’m going to assume for the purposes of this answer that a spherical approximation is good enough, and that your points are at similar enough altitudes that we don’t need to worry about their heights.
You can convert a geographical point (ψ, λ) to Cartesian Earth-centred coordinates using the transformation
(ψ, λ) → (a cos(ψ) cos(λ), a cos(ψ) sin(λ), a sin(ψ))
where a is the mean radius of the Earth (6,371 km). So let’s suppose that the two points that define your line are p₀ and p₁; then the shortest line through p₀ and p₁ is a great circle, which defines a plane that slices the Earth into two halves, with normal n = p₀ × p₁.
Now we need to find the border of the circular region. Suppose the centre of this region is at c and that the surface radius of the region is s. Then the straight-line radius of the region is r = a sin(s/a). We’ll also need the true centre of the circular region, c’ = c cos(s/a). (This point is buried deep underground!)
We’d like to intersect the two circles and solve for the points of intersection. Unfortunately, because of numerical imprecision, the chances are that this procedure will never find any solutions because the imprecise circles will miss each other in 3 dimensions. So I suggest the following procedure: intersect the planes of the two circles, getting the dotted line shown below (unless c’ × n = 0 in which case the two circles are parallel and either c’ = o, in which case they are coincident, or else they do not intersect). Then intersect the line with the circular region.
This two-step procedure reduces the problem to two dimensions, and guarantees that a solution will be found even if numerical imprecision makes the two circles miss in 3 dimensions.
If you need more accuracy than this, then you might need to use geodetic coordinates on a reference ellipsoid such as WGS 1984.
I'd say find the closest point on the line to the center of the circle, then determine whether that point is within the circle (i.e. the distance in question is less than or equal to the circle's radius).
Outline for solving the problem: assume the Earth is a sphere of radius one centered at the origin. Convert all three lat, lon points to 3D coordinates. The two points of the line plus the origin define a plane; intersect that plane with the sphere of radius d centered on the other point. If there is no plane-sphere intersection, then the answer is the line does not intersect the region. If there is a plane-sphere intersection, then the problem is simplified to intersecting the circular region defined by the plane-sphere intersection with the shortest circular arc on the plane going between the end points of the line and centered at the origin. This is a straightforward 2D problem if you convert to the coordinate system of the plane.
This question is too vague to be answered precisely. What do you mean by
a line form by 2 geo points (lat, lon)
This can be either a great circle going through them (also called orthodrome) or it a can be a linear function of spherical coordinates (loxodrome).
BTW, I assume your circle is a circle on the surface of the sphere, right?
Assuming line is formed by points (x1, y1) and (x2, y2), and circle has radius r with origin (0,0):
Calculate:
Incidence = r^2 * [(x2 - x1)^2 + (y2 - y1)^2] - (x1 * y2 - x2 * y1)^2
Then, from the value of Incidence, we can determine the following:
Incidence < 0: No intersection
Incidence = 0: Tangent (intersection at 1 point on circle)
Incidence > 0: Intersection
It's likely your circle is not at the origin (0,0), so to fix this, just add the origin coordinates from your line coordinates in the equation above. So, if the circle is at (x3, y3), x1 in the above equation would become x1 + x3. Likewise, y1 would be y1 + y3, and the same goes for x2 and y2.
For more info check out this link