Good day.
I have the task of finding the set of points in 2D space for which the sum of the distances to the rectangles is minimal. For example, for two rectangles, the result will be the next area (picture). Any point in this area has the minimum sum of lengths to A and B rectangles.
Which algorithm is suitable for finding a region, all points of which have the minimum sum of lengths? The number of rectangles can be different, they are randomly located. They can even overlap each other. The sides of the rectangles are parallel to the coordinate axes and cannot be rotated. The region must be either a rectangle or a line or a point.
Hint:
The distance map of a rectangle (function that maps any point (x,y) to the closest distance to the rectangle) is made of four slanted planes (slope 45°), four quarter of cones and the rectangle itself, which is at ground level, forming a continuous surface.
To obtain the global distance map, it "suffices" to sum the distance maps of the individual rectangles. A pretty complex surface will result. Depending on the geometries, the minimum might be achieved on a single vertex, a whole edge or a whole face.
The construction of the global map seems more difficult than that of a line arrangement, due to the conic patches. A very difficult problem in the general case, though the axis-aligned constraint might ease it.
Add on Yves's answer.
As Yves described, each rectangle 'divide' plane into 9 parts and adds different distance method in to the sum. Middle part (rectangle) add distance 0, side parts add coordinate distance to that side, corner parts add point distance to that corner. With that approach plan has to be divided into 9^n parts, and distance sum is calculated by adding appropriate rectangle distance functions. That is feasible if number of rectangles is not too large.
Probably it is not needed to calculate all parts since it is easy to calculate some bound on part min value and check is it needed to calculate part at all.
I am not sure, but it seems to me that global distance map is convex function. If that is the case than it can be solved iteratively by similar idea as in linear programming.
I have an image of a circle but my circle is not perfect
Firstly I found transition coordinates
Detecting Circles without using Hough Circles
and than ı use this formula https://math.stackexchange.com/questions/675203/calculating-centre-of-rotation-given-point-coordinates-at-different-positions/1414344#1414344
Finally ı have fourn radiuses which the longest and shortest
Now I have this image:
BUt they are radius I need to find diameter How to find diameter from image??
Or How to I can find mutual/symetric/ point in a circle
For this image, the approaches mentioned are overkill. Just find the bounding box of the non-black pixels. Because of sampling artifacts, the horizontal and vertical side lengths may differ by one or two pixels.
If I am right, the outer circle is 277 x 273 pixels. If you consider the difference to be significant, then this is an ellipse, not a circle.
3 ways to do this:
I think you need to measure it from image:
so use edge detection (blue line width from left to right = width of bounding box of the blue pixels) then count pixels.
If you need then convert to any unit you want like inch (using pixel per inch).
If your circle is not perfect circle (stretched) measure in many direction so you can find its deviation too.
There is another way named Monte-Carlo method:
first generate random x and y (inside square) and then evaluate that point (x, y) is inside the circle or not and count the number of inside occurrences, then you can calculate the Area of circle using ratio on inside count/total (and therefore diameter).
without using random numbers:
fill(color) circle inside then simply count black pixels this is = to Area outside circle => Total Area(Square Area)- black pixel Area = Circle Area => calculate diameter.
I have a set of points on the unit sphere and a corresponding set of values being equal, for simplicity, to 0 and 1. Thus I'm constructing the characteristic function of a set on the sphere. Typically, I have several such sets, which form a partition of the sphere. An example is given in the figure.
I was wondering if paraview can find boundaries between the cells and compute the length and the curvature of the boundaries.
I read in a paper that using gradient reconstruction the guys managed to find the curvature of such contours. I imagine that if the curvature can be found, the length should be somewhat simpler. If the answer to the above question is yes, where should I look for the corresponding documentation?
For points on the sphere if they are build based on great-circle distance principle, it means all lines connecting points are of a shortest distance and plane goes through sphere center. In such case angle could be computed as arccos of scalar product.
R = 1;
angle = arccos(x1*x2 + y1*y2 + z1*z2);
length = R*angle;
And parametric line from p1 to p2 could be build using slerp interpolation.
slerp(t) = sin((1.0-t)*angle)/sin(angle)*p1 + sin(t*angle)/sin(angle)*p2;
where t is in [0...1] range
In such case curvature is 1/R for all great circle lines. That would be first thing I would try - try to match actual boundaries with those made from great-circle approach. If they match, that's the answer
Links
https://en.wikipedia.org/wiki/Great_circle
https://en.wikipedia.org/wiki/Great-circle_distance
https://en.wikipedia.org/wiki/Slerp
UPDATE
In case of non-great arcs I would propose following modification. Build great arc plane which goes through sphere center and on intersection with surface makes great arc between the points. Fix axis as a line going through those two points. Start rotating great arc plane along above mentioned axis till you get the exactly your arc of circle connecting two points. At this moment you could get rotation angle, compute your circle plane position and radius r, curvature as 1/r etc
let's say I have a huge set of non-overlapping rectangle with integer coordinates, who are fixed once and for all
I have another rectangle A with integer coordinates whose coordinates are moving (but you can assume that its size is constant)
What is the most efficient way to find which rectangles are intersecting (or inside) A?
I cannot simply loop through my set as it is too big. Thanks
edit : the rectangles are all parallel to the axis
I'll bet you could use some kind of derivation of a quadtree to do this. Take a look at this example.
Personally, I would solve this with a KD-Tree or a BIH-Tree. They are both adaptive spatial data structures that have a log(n) search time. I have an implementation of both for my Ray Tracer, and they scream.
-- UPDATE --
Store all of your fixed rectangles in the KD-Tree. When you are testing intersections, iterate through the KD-Tree as follows:
function FindRects(KDNode node, Rect searchRect, List<Rect> intersectionRects)
// searchRect is the rectangle you want to test intersections with
// node is the current node. This is a recursive function, so the first call
// is the root node
// intersectionRects contains the list of rectangles intersected
int axis = node.Axis;
// Only child nodes actually have rects in them
if (node is child)
{
// Test for intersections with each rectangle the node owns
for each (Rect nRect in node.Rects)
{
if (nRect.Intersects(searchRect))
intersectionRects.Add(nRect);
}
}
else
{
// If the searchRect's boundary extends into the left bi-section of the node
// we need to search the left sub-tree for intersections
if (searchRect[axis].Min // Min would be the Rect.Left if axis == 0,
// Rect.Top if axis == 1
< node.Plane) // The absolute coordinate of the split plane
{
FindRects(node.LeftChild, searchRect, intersectionRects);
}
// If the searchRect's boundary extends into the right bi-section of the node
// we need to search the right sub-tree for intersections
if (searchRect[axis].Max // Max would be the Rect.Right if axis == 0
// Rect.Bottom if axis == 1
> node.Plane) // The absolute coordinate of the split plane
{
FindRects(node.RightChild, searchRect, intersectionRects);
}
}
This function should work once converted from pseudo-code, but the algorithm is correct. This is a log(n) search algorithm, and possibly the slowest implementation of it (convert from recursive to stack based).
-- UPDATE -- Added a simple KD-Tree building algorithm
The simplest form of a KD tree that contains area/volume shapes is the following:
Rect bounds = ...; // Calculate the bounding area of all shapes you want to
// store in the tree
int plane = 0; // Start by splitting on the x axis
BuildTree(_root, plane, bounds, insertRects);
function BuildTree(KDNode node, int plane, Rect nodeBds, List<Rect> insertRects)
if (insertRects.size() < THRESHOLD /* Stop splitting when there are less than some
number of rects. Experiment with this, but 3
is usually a decent number */)
{
AddRectsToNode(node, insertRects);
node.IsLeaf = true;
return;
}
float splitPos = nodeBds[plane].Min + (nodeBds[plane].Max - nodeBds[plane].Min) / 2;
// Once you have a split plane calculated, you want to split the insertRects list
// into a list of rectangles that have area left of the split plane, and a list of
// rects that have area to the right of the split plane.
// If a rect overlaps the split plane, add it to both lists
List<Rect> leftRects, rightRects;
FillLists(insertRects, splitPos, plane, leftRects, rightRects);
Rect leftBds, rightBds; // Split the nodeBds rect into 2 rects along the split plane
KDNode leftChild, rightChild; // Initialize these
// Build out the left sub-tree
BuildTree(leftChild, (plane + 1) % NUM_DIMS, // 2 for a 2d tree
leftBds, leftRects);
// Build out the right sub-tree
BuildTree(rightChild, (plane + 1) % NUM_DIMS,
rightBds, rightRects);
node.LeftChild = leftChild;
node.RightChild = rightChild;
There a bunch of obvious optimizations here, but build time is usually not as important as search time. That being said, a well build tree is what makes searching fast. Look up SAH-KD-Tree if you want to learn how to build a fast kd-tree.
You can create two vectors of rectangle indexes (because two diagonal points uniquely define your rectangle), and sort them by one of coordinates. Then you search for overlaps using those two index arrays, which is going to be logarithmic instead of linear complexity.
You can do a random "walking" algorithm ... basically create a list of neighbors for all your fixed position rectangles. Then randomly pick one of the fixed-position rectangles, and check to see where the target rectangle is in comparison to the current fixed-position rectangle. If it's not inside the rectangle you randomly picked as the starting point, then it will be in one of the eight directions which correspond to a given neighbor of your current fixed position rectangle (i.e., for any given rectangle there will be a rectangle in the N, NE, E, SE, S, SW, W, NW directions). Pick the neighboring rectangle in the closest given direction to your target rectangle, and re-test. This is essentially a randomized incremental construction algorithm, and it's performance tends to be very good for geometric problems (typically logarithmic for an individual iteration, and O(n log n) for repeated iterations).
Create a matrix containing "quadrant" elements, where each quadrant represents an N*M space within your system, with N and M being the width and height of the widest and tallest rectangles, respectively. Each rectangle will be placed in a quadrant element based on its upper left corner (thus, every rectangle will be in exactly one quadrant). Given a rectangle A, check for collisions between rectangles in the A's own quadrant and the 8 adjacent quadrants.
This is an algorithm I recall seeing recommended as a simple optimization to brute force hit-tests in collision detection for game design. It works best when you're mostly dealing with small objects, though if you have a couple large objects you can avoid wrecking its efficiency by performing collision detection on them separately and not placing them in a quadrant, thus reducing quadrant size.
As they are not overlapping I would suggest an approach similar (but not equal) to Jason Moore (B).
Sort your array by x of upper left corner.
And sort a copy by y of upper left corner. (of course you would just sort pointers to them to save memory).
Now you once create two sets Sliding_Window_X and Sliding_Window_Y.
You search with binary search once your x-coordinate (upper left) for your A window in the x-sorted array and your y-coordinate. You put your results into the corrospondng Sliding_Window_Set. Now you add all following rectangles in the ordered array that have a lower x(y) (this time lower right) coordinate than your lower right of A.
The result is that you have in your Sliding_Window-sets the windows that overlap with your A in one coordinate. The overlapping of A is the intersection of Sliding_Window_X and _Y.
The Sliding_Window sets can be easily represented by just 2 numbers (begin and end index of the corrosponding sorted array).
As you say you move A, it is now really easy to recalculate the overlap. Depending on the direction you can now add/remove Elements to the Sliding_Window set. I.e. you take just the next element from the sorted array at the front/end of the set and maybe remove on at the end.
Topcoder provides a way to determine if a point lies within a rectangle. It says that say we have a point x1,y1 and a rectangle. We should choose a random point very far away from current locality of reference in the rectangular co-ordinate system say x2,y2.
Now we should make a line segment with the points x1,y1 and x2,y2. If this line segment intersects odd number of sides of the given rectangle (it'll be 1 in our case, this method can be extended to general polygons as well) then the point x1,y1 lies inside the rectangle and if it intersects even number of sides it lies outside the rectangle.
Given two rectangles, we need to repeat this process for every vertex of 1 triangle to possibly lie in the second triangle. This way we'd be able to determine if two rectangles overlap even if they are not aligned to the x or y axis.
Interval Trees: Are BSTs designed with taking 'lo' value as key in an interval. So, for example if we want to insert (23, 46) in the tree, we'd insert it using '23' in the BST.
Also, with interval trees at each node, we keep the maximum endpoint (hi value) of the sub-tree rooted at that node.
This order of insertion allows us to search all 'R' intersections in R(logN) time. [We search for first intersection in logN time and all R in RlogN time] Please refer to interval trees documentation for how insert, search is done and details of complexity.
Now for this problem, we use an algorithm known as sweep-line algorithm. Imagine we have a vertical line (parallel to y-axis) which is sweeping the 2D space and in this process intersects with the rectangles.
1) Arrange rectangles in increasing order of x-cordinates (left-edge wise) either via priority queue or via sorting . Complexity NlogN if N rectangles.
2) As this line sweeps from left to right, following are the intersection cases:
If line intersects the left side of a rectangle never seen, add the y co-ords of the rectangle's side to the interval tree. [say (x1,y1) and (x1,y2) are left edge co-ordinates of the rectangle add interval (y1, y2) to the interval tree] ---> (NlogN)
Do a range search on the interval tree. [say (x1,y1) and (x1,y2) are left edge co-ordinates of the rectangle, take the interval (y1,y2) and do an interval intersection query on the tree to find all intersections] ---> RlogN (in practice)
If line intersects the right side of a rectangle, remove it's y-coords from the interval tree as the rectangle is now processed completely. ----> NlogN
Total complexity : NlogN + RlogN
Let your set of rectangle be (Xi1,Yi1,Xi2,Yi2) where i varies from 0 to N.
Rectangle A and B can NOT be intersecting if Ax1 > Bx2 || Ay1 < By2 || Bx1 > Ax2 || By1 < Ay2.
Create tree which is optimized for range/interval (For exa: segment tree or interval tree)
See http://w3.jouy.inra.fr/unites/miaj/public/vigneron/cs4235/l5cs4235.pdf
Use this tree to find set of triangle while your triangle is changing coordinates.
By calculating the area of each rectangle and and checking the length L, height H and area of rectangles whether exceeds or not the length and height and area of a rectangle A
Method (A)
You could use an interval tree or segment tree. If the trees were created so that they would be balanced this would give you a run time of O(log n). I assume this type of preprocessing is practical because it would only happen once (it seems like you are more concerned with the runtime once the rectangle starts moving than you are with the amount of initial preprocessing for the first time). The amount of space would be O(n) or O(n log n) depending on your choice above.
Method (B)
Given that your large set of rectangles are of fixed size and never change their coordinates and that they are non-overlapping, you could try a somewhat different style of algorithm/heuristic than proposed by others here (assuming you can live with a one-time, upfront preprocessing fee).
Preprocessing Algorithm [O(n log n) or O(n^2) runtime {only run once though}, O(n) space]
Sort the rectangles by their horizontal coordinates using your favorite sorting algorithm (I am assuming O(n log n) run time).
Sort the rectangles by their vertical coordinates using your favorite sorting algorithm (I am assuming O(n log n) run time)
Compute a probability distribution function and a cumulative distribution function of the horizontal coordinates. (Runtime of O(1) to O(n^2) depending on method used and what kind of distribution your data has)
a) If your rectangles' horizontal coordinates follow some naturally occurring process then you can probably estimate their distribution function by using a known distribution (ex: normal, exponential, uniform, etc.).
b) If your rectangles' horizontal coordinates do not follow a known distribution, then you can calculate a custom/estimated distribution by creating a histogram.
Compute a probability distribution function and a cumulative distribution function of the vertical coordinates.
a) If your rectangles' vertical coordinates follow some naturally occurring process then you can probably estimate their distribution function by using a known distribution (ex: normal, exponential, uniform, etc.).
b) If your rectangles' vertical coordinates do not follow a known distribution, then you can calculate a custom/estimated distribution by creating a histogram.
Real-time Intersection Finding Algorithm [Anywhere from O(1) to O(log n) to O(n) {note: if O(n), then the constant in front of n would be very small} run time depending on how well the distribution functions fit the dataset]
Taking the horizontal coordinate of your moving rectangle and plug it into the cumulative density function for the horizontal coordinates of the many rectangles. This will output a probability (value between 0 and 1). Multiply this value times n (where n is the number of many rectangles you have). This value will be the array index to check in the sorted rectangle list. If the rectangle of this array index happens to be intersecting then you are done and can proceed to the next step. Otherwise, you have to scan the surrounding neighbors to determine if the neighbors intersect with the moving rectangle. You can attack this portion of the problem multiple ways:
a) do a linear scan until finding the intersecting rectangle or finding a rectangle on the other side of the moving rectangle
b) calculate a confidence interval using the probability density functions you calculated to give you a best guess at potential boundaries (i.e. an interval where an intersection must lie). Then do a binary search on this small interval. If the binary search fails then revert back to a linear search in part (a).
Do the same thing as step 1, but do it for the vertical portions rather than the horizontal parts.
If step 1 yielded an intersection and step 2 yielded an intersection and the intersecting rectangle in step 1 was the same rectangle as in step 2, then the rectangle must intersect with the moving rectangle. Otherwise there is no intersection.
Use an R+ tree, which is most likely precisely the specific tree structure you are looking for. R+ trees explicitly do not allow overlapping in the internal (non-leaf) structure in exchange for speed. As long as no object exists in multiple leaves at once, there is no overlap. In your implementation, rather than support overlap, whenever an object needs to be added to multiple leaves, just return true instead.
Here is a detailed description of the data structure, including how to manage rectangles:
The R+-tree: A dynamic index for multi-dimensional objects
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Finding whether a point lies inside a rectangle or not
There is an interview question that is, "How to determine whether a point lies inside a rectangle"
Note that the rectangle could be rotated as well. So the simple solution of checking point inside the rectangle doesn't stands valid here...
Please share your thoughts on this question..
I found a link on internet, and was trying to understand it, but failed.... Please if any body out here can give complete solution with bit of computer graphics logic, because i have forgotten all the basics....
How to determine if a point is inside rectangle.
Pick a point that's definitely outside the rectangle. Then create a segment from that point to the point in question. Solve the linear equations for intersections between that segment and the segments that make up the rectangle. If you get exactly one intersection, the point is inside the rectangle. Otherwise (0 or 2 intersections), it's outside.
This is trivial to extend to essentially any polygon -- an odd number of intersections means the point is inside the polygon, and an even number means it's outside.
Edit: It may not be immediately obvious, so I'll emphasize that the point we pick outside the rectangle (polygon) is entirely arbitrary. We can pick whatever point we want as long as we're sure it's outside the polygon. To keep our computations easy, what we'll typically do is pick (Px, infinity) (where Px is the x coordinate of the point P that we're testing) -- that is, what we're creating is essentially a vertical ray. That simplifies testing a bit, because we only have to test against one end-point to find an intersection. It also simplifies solving the linear equations to the point that it's barely recognizable as solving linear equations anymore. We really just need to compute the Y coordinate for the line at the Px, and see if it's greater than Py. As such, solving the linear equation breaks down to:
checking whether that X value is within the range of X values for the segment
if it is, plugging the X value into the equation of the line
testing whether the resulting Y value is greater than Py
If those pass, we have an intersection. Also note that the tests can be carried out in parallel (handy if we're doing this on parallel hardware like a GPU).
Simple solution that works in N dimensions for convex polyhedra, of which a 2-dimensional rectangle is a special case:
Represent the polyhedron as the intersection of half-spaces, each defined by a unit normal vector and the distance of the surface hyperplane from the origin along the normal.
For each of these half-spaces, take the dot product of point in question with the defining normal vector. The point is in the half-space if and only if the dot product is less than [or equal to] the defining distance.
The point is inside the polyhedron if and only if it's in every one of the half-spaces.
For a rectangle defined as a counter-clockwise sequence of edges, step 1 amounts to rotating the edges each by 90 degrees clockwise to get the normals, then intersecting the normal line with the line containing the edge to find the distance to the origin.
Assuming step 1 is complete, testing a point takes at most 8 multiplications, 4 additions, and 4 comparisons.
If you want to, you can optimize the process a bit since you have rectangles (and thus opposite sides have opposite normals). Now you're only looking at 2 normals rather than 4, and a range of dot product values which indicate points that lie between the opposite sides. So now you're down to 4 multiplications, 2 additions, and 4 comparisons.
You can also get lucky if the first test you make shows that the point is outside the rectangle, in which case it's just 2 multiplications, 1 addition, and 1-2 comparisons.
This is far from the best solution... But if you have the points in consecutive order, call them a, b, c, and d with an x and a y field, you can use the cross product of the vectors between your point p and each of the consecutive pairs.
If you always get the same sign for the result (i.e., all are positive or all are negative) then you're inside the rectangle; otherwise, you're outside.
Define a new coordinate system with two rectangle sides as unit vectors and transform the coordinate of the point into the new coordinate system. If both coordinates are between 0 and 1, it's inside.
In equations (assuming A,B,C,D are corners of the rectangle, P is the point, _x and _y are the x and y components):
P_x = A_x + x * (B_x - A_x) + y * (D_x - A_x)
P_y = A_y + x * (B_y - A_y) + y * (D_y - A_y)
Solve for x and y and check if they are between 0 and 1
Written as linear equation system (A,B,C,D,P are vectors of length 2):
[ | ] [x] [ ]
[B-A | D-A] * [ ] = [P-A]
[ | ] [y] [ ]
Solving is easy as it has only two dimensions and you can be sure that you are not singular.
You can rotate and move your reference system so it matches position and rotation of the rectangle. Now it is just a matter of simple comparisons between coordinates. This is more a mathematical way, so not the fastest (bellieve #Platinum Azure's one is)
Since the rectangle could be rotated, you might want to consider an algorithm that is used to determine whether a point is interior to a convex polygon.
You could also compute the rotation angle of the rectangle, then transform both the rectangle and the point to axially align the rectangle. Then check to see if the transformed point is inside the axially aligned rectangle.
Finding whether a point lies within a bounded region like rectangle is part of the classic clipping algorithms. Refer to the wikipedia articles on Clipping and Line Clipping to know more about it.
Following the spirit of #Jerry Coffin: create segments from rectangle corners to the point in question. Solve the linear equations. Slope is tan(a). Sum up all seq arctangents diff, if it is 2*PI and each diff < PI - point is inside the rectangle.
Edit Probably enough just check for each sequential difference < Pi...