I am having trouble figuring out the math for a problem I am having.
I have an n by m rectangle and need to place k points in it such that points are, as close as possible, completely equidistant from each other.
Normally this is pretty easy, I construct the regular polygon with k points on it, center it in the center of my rectangle, stretch it to fit and voila, its vertices are my output points.
The catch is that when calculating distances on this rectangle, you can wrap. As such the point (0,0) is just 1 pixel away from the point (n-1,m-1) (using 0-indexed coordinates).
I've been messing around a bit on paper and getting nowhere fast with this. Does anybody have any idea how to calculate this?
tl;dr:
Inputs: n - width of rectangle, m - height of rectangle, k - number of points
Outputs: k pairs of (x,y) coordinates
Constraints: the output coordinates are equidistant from one another under wrapping coordinate systems.
Any advice on where I could look for such a geometry problem?
Related
I am aiming to create the following (a directed arrow that connects two nodes) :
At the moment I have this (a quadratic bezier curve drawn from the center point of one node to the center of another):
(Note I have drawn the bezier above the nodes to show where it begins and ends)
I need a method - heuristic or otherwise - to calculate the point of intersection (circled in red, above) between the bezier curve and the node's (ellipse) circumference.
With this, I could calculate the angle between the node center and the point of intersection to draw the arrow head lines at the correct location and angle.
As a last resort, I could use the quadratic Bézier formula to generate a list of points that lie along the curve and also generate a list of points that lie on the circumference of the circle and use one of the two coordinates that have the least euclidian distance between each other as my intersection point. I'm hoping any answers can leverage geometry or whatever else to better solve it.
The general problem is uneasy as the intersection equation is quartic ((X(t)-Xc)² + (Y(t)-Yc)²=R²), where X and Y are quadratic polynomials). If you have a quartic solver handy you can use it but you'll have to select the right root.
A more reasonable approach is just to intersect the circle with the line segment between the control points. This is approximate but probably unnoticeable if the circle radius is small.
If you want more accuracy, perform one or two Newton's iterations from this point.
I'm looking for an algorithm that will find an irregular shape, maybe not too irregular, like a squashed circle, on a surface, and trace a polygon of a maximum of n sides around the shape. The 'n' maximimum might be based on the area of the shape.
I would do it like this:
compute tangent angles ang and its change dang for all curve segments
you can use atanxy or atan2 for that
ang[i] = atanxy(x[i]-x[i-1],y[i]-y[i-1]);
dang[i] = ang[i]-ang[i-1];
find inflex points (Black)
at these points the sign of dang is changing so
dang[i-1]*dang[i+1]<0.0
but you need to handle the dang=0.0 elements properly (need to scan before and after them). These points will be the fundamental skeleton for your output polygon
add the bumps max points (green)
at these points the tangent angle is between nearest inflex points so to find max point between two inflex points i0 and i1 find the closest angle to
angavg=0.5*(ang[i0]+ang[i1])
do not forget that
|ang[i]-angavg|<=PI
so +/- 2.0*PI if this is not true
now you should have all significant points of your closed polycurve ...
it should look like this:
CW/CCW or Red/Blue just represents the sign of dang[i] ...
[Notes]
The output point type should be preserved (inflex/maxpoint) because it can be later used for comparison and detection of shapes ...
Suppose I have a set of points in the Cartesian plane, defined by an array/vector of (X,Y) coordinates. This set of points will be "contiguous" in the coordinate plane, if any set of discontinuous points can be contiguous. That is, these points originated as a rectangular grid in which regions of points were eliminated by a prior algorithm. The shape outlined by the points is arbitrary, but it will tend to have arcs for edges.
Suppose further that I can create circles of fixed radius r.
I would like an algorithm that will find me the center X,Y for a circle that will enclose as close to exactly half of the given points as possible.
OK, try this (sorry if I have very bad wording: I didn't learn my Maths in english)
Step 1: Find axis
For all pairs of points, that are less than 2r apart calculate how many points lie on either side of the connecting line
Chose the pair with the worst balance
Calculate the line, that bisects these two points as an axis ("Axis of biggest concavity")
Step 2: Find center
Start on the axis far (>2r) away on the side, that had the lower point count in step 1 (The concave side)
Move the center on the axis, until you reach the desired point. This can be done by moving up with a step of sqrt(delta), where delta is the smallest distance between 2 points in the set, if overreaching move back halfing the step, etc.
You might want to look into the algorithm for smallest enclosing circle of a point set.
A somewhat greedy algorithm would be to simply remove points 1 at a time until the circle radius is less or equal to r.
I've just implemented collision detection using SAT and this article as reference to my implementation. The detection is working as expected but I need to know where both rectangles are colliding.
I need to find the center of the intersection, the black point on the image above (but I don't have the intersection area neither). I've found some articles about this but they all involve avoiding the overlap or some kind of velocity, I don't need this.
The information I've about the rectangles are the four points that represents them, the upper right, upper left, lower right and lower left coordinates. I'm trying to find an algorithm that can give me the intersection of these points.
I just need to put a image on top of it. Like two cars crashed so I put an image on top of the collision center. Any ideas?
There is another way of doing this: finding the center of mass of the collision area by sampling points.
Create the following function:
bool IsPointInsideRectangle(Rectangle r, Point p);
Define a search rectangle as:
TopLeft = (MIN(x), MAX(y))
TopRight = (MAX(x), MAX(y))
LowerLeft = (MIN(x), MIN(y))
LowerRight = (MAX(x), MIN(y))
Where x and y are the coordinates of both rectangles.
You will now define a step for dividing the search area like a mesh. I suggest you use AVG(W,H)/2 where W and H are the width and height of the search area.
Then, you iterate on the mesh points finding for each one if it is inside the collition area:
IsPointInsideRectangle(rectangle1, point) AND IsPointInsideRectangle(rectangle2, point)
Define:
Xi : the ith partition of the mesh in X axis.
CXi: the count of mesh points that are inside the collision area for Xi.
Then:
And you can do the same thing with Y off course. Here is an ilustrative example of this approach:
You need to do the intersection of the boundaries of the boxes using the line to line intersection equation/algorithm.
http://en.wikipedia.org/wiki/Line-line_intersection
Once you have the points that cross you might be ok with the average of those points or the center given a particular direction possibly. The middle is a little vague in the question.
Edit: also in addition to this you need to work out if any of the corners of either of the two rectangles are inside the other (this should be easy enough to work out, even from the intersections). This should be added in with the intersections when calculating the "average" center point.
This one's tricky because irregular polygons have no defined center. Since your polygons are (in the case of rectangles) guaranteed to be convex, you can probably find the corners of the polygon that comprises the collision (which can include corners of the original shapes or intersections of the edges) and average them to get ... something. It will probably be vaguely close to where you would expect the "center" to be, and for regular polygons it would probably match exactly, but whether it would mean anything mathematically is a bit of a different story.
I've been fiddling mathematically and come up with the following, which solves the smoothness problem when points appear and disappear (as can happen when the movement of a hitbox causes a rectangle to become a triangle or vice versa). Without this bit of extra, adding and removing corners will cause the centroid to jump.
Here, take this fooplot.
The plot illustrates 2 rectangles, R and B (for Red and Blue). The intersection sweeps out an area G (for Green). The Unweighted and Weighted Centers (both Purple) are calculated via the following methods:
(0.225, -0.45): Average of corners of G
(0.2077, -0.473): Average of weighted corners of G
A weighted corner of a polygon is defined as the coordinates of the corner, weighted by the sin of the angle of the corner.
This polygon has two 90 degree angles, one 59.03 degree angle, and one 120.96 degree angle. (Both of the non-right angles have the same sine, sin(Ɵ) = 0.8574929...
The coordinates of the weighted center are thus:
( (sin(Ɵ) * (0.3 + 0.6) + 1 - 1) / (2 + 2 * sin(Ɵ)), // x
(sin(Ɵ) * (1.3 - 1.6) + 0 - 1.5) / (2 + 2 * sin(Ɵ)) ) // y
= (0.2077, -0.473)
With the provided example, the difference isn't very noticeable, but if the 4gon were much closer to a 3gon, there would be a significant deviation.
If you don't need to know the actual coordinates of the region, you could make two CALayers whose frames are the rectangles, and use one to mask the other. Then, if you set an image in the one being masked, it will only show up in the area where they overlap.
I have two 2D rectangles, defined as an origin (x,y) a size (height, width) and an angle of rotation (0-360°). I can guarantee that both rectangles are the same size.
I need to calculate the approximate area of intersection of these two rectangles.
The calculation does not need to be exact, although it can be. I will be comparing the result with other areas of intersection to determine the largest area of intersection in a set of rectangles, so it only needs to be accurate relative to other computations of the same algorithm.
I thought about using the area of the bounding box of the intersected region, but I'm having trouble getting the vertices of the intersected region because of all of the different possible cases:
I'm writing this program in Objective-C in the Cocoa framework, for what it's worth, so if anyone knows any shortcuts using NSBezierPath or something you're welcome to suggest that too.
To supplement the other answers, your problem is an instance of line clipping, a topic heavily studied in computer graphics, and for which there are many algorithms available.
If you rotate your coordinate system so that one rectangle has a horizontal edge, then the problem is exactly line clipping from there on.
You could start at the Wikipedia article on the topic, and investigate from there.
A simple algorithm that will give an approximate answer is sampling.
Divide one of your rectangles up into grids of small squares. For each intersection point, check if that point is inside the other rectangle. The number of points that lie inside the other rectangle will be a fairly good approximation to the area of the overlapping region. Increasing the density of points will increase the accuracy of the calculation, at the cost of performance.
In any case, computing the exact intersection polygon of two convex polygons is an easy task, since any convex polygon can be seen as an intersection of half-planes. "Sequential cutting" does the job.
Choose one rectangle (any) as the cutting rectangle. Iterate through the sides of the cutting rectangle, one by one. Cut the second rectangle by the line that contains the current side of the cutting rectangle and discard everything that lies in the "outer" half-plane.
Once you finish iterating through all cutting sides, what remains of the other rectangle is the result.
You can actually compute the exact area.
Make one polygon out of the two rectangles. See this question (especially this answer), or use the gpc library.
Find the area of this polygon. See here.
The shared area is
area of rectangle 1 + area of rectangle 2 - area of aggregated polygon
Take each line segment of each rectangle and see if they intersect. There will be several possibilities:
If none intersect - shared area is zero - unless all points of one are inside the other. In that case the shared area is the area of the smaller one.
a If two consecutive edges of one rectactangle intersect with a single edge of another rectangle, this forms a triangle. Compute its area.
b. If the edges are not consequtive, this forms a quadrilateral. Compute a line from two opposite corners of the quadrilateral, this makes two triangles. Compute the area of each and sum.
If two edges of one intersect with two edges of another, then you will have a quadrilateral. Compute as in 2b.
If each edge of one intersects with each edge of the other, you will have an octagon. Break it up into triangles ( e.g. draw a ray from one vertex to each other vertex to make 4 triangles )
#edit: I have a more general solution.
Check the special case in 1.
Then start with any intersecting vertex, and follow the edges from there to any other intersection point until you are back to the first intersecting vertex. This forms a convex polygon. draw a ray from the first vertex to each opposite vetex ( e.g. skip the vertex to the left and right. ) This will divide it into a bunch of triangles. compute the area for each and sum.
A brute-force-ish way:
take all points from the set of [corners of
rectangles] + [points of intersection of edges]
remove the points that are not inside or on the edge of both rectangles.
Now You have corners of intersection. Note that the intersection is convex.
sort the remaining points by angle between arbitrary point from the set, arbitrary other point, and the given point.
Now You have the points of intersection in order.
calculate area the usual way (by cross product)
.