Given a rectangle and two points on the borders of the rectangle, where these two points will never share the same border, draw a line connecting these two points. Find the area of the two polygons formed by dividing the rectangle with this line. I am looking for an algorithm to find these two areas.
This seems like an easy problem but I couldn't find a consistent way to write the algorithm.
Here is an illustration of the problem with some example cases:
If we examine the 6 possible configurations we see that in all cases the area of one polygon is equal to half the area of the rectangle formed by the endpoints of the line (red), plus an additional rectangle (green) in the case where the line spans the width or height of the outer rectangle.
The area of one polygon is therefore given by:
r1, r2 : corner points of the rectangle
p1, p2 : endpoints of the line
area = abs(p1.x - p2.x) * abs(p1.y - p2.y) / 2
if abs(p1.x - p2.x) == abs(r1.x - r2.x)
area = area + abs(r1.x - r2.x) * (min(p1.y, p2.y) - min(r1.y, r2.y))
else if abs(p1.y - p2.y) == abs(r1.y - r2.y)
area = area + abs(r1.y - r2.y) * (min(p1.x, p2.x) - min(r1.x, r2.x))
Given two points of the straight line, you can pick the other two points from the corners of the rectangle to get the quadrilateral and then you could use the shoelace formula to compute the area of that quadrilateral.
If you find one quadrilateral area, you can find the other area just by subtracting first quadrilateral's area from the area of the whole rectangle.
There are 2 cases in total. Let say A and B are the number of corners on the left and right side of the red line, respectively.
Case 1: A = B = 2, then there are 2 trapezoids.
Case 2: A = 1 or B = 1, then there is at least 1 triangle.
Related
I encountered this challenge in
codesignal (The core, question 49).
Here is the problem:
A rectangle with sides equal to even integers a and b is drawn on the Cartesian plane. Its center (the intersection point of its diagonals) coincides with the point (0, 0), but the sides of the rectangle are not parallel to the axes; instead, they are forming 45 degree angles with the axes.
How many points with integer coordinates are located inside the given rectangle (including on its sides)?
Example:
I also have the solution in JS, by another user:
function solution(a, b) {
var pointsA = Math.floor(Math.sqrt(a * a / 2)),
pointsB = Math.floor(Math.sqrt(b * b / 2));
return (pointsA * pointsB + Math.floor((pointsA + pointsB) / 2)) * 2 + 1;
}
However I cannot understand it. Although the theme of the challenge is nested loop, I still want to understand the math behind this solution. Please explain it to me. Thank you.
The diagonal of a grid cell has length √2. So the number of oblique rows contained in the rectangle is determined by the integer parts of a/√2 and b/√2. The count of grid nodes is just the product of these numbers of rows, with an adjustment term that accounts for the parities of every other row.
Hi sorry for the confusing title.
I'm trying to make a race track using points. I want to draw 3 rectangles which form my roads. However I don't want these rectangles to overlap, I want to leave an empty space between them to place my corners (triangles) meaning they only intersect at a single point. Since the roads have a common width I know the width of the rectangles.
I know the coordinates of the points A, B and C and therefore their length and the angles between them. From this I think I can say that the angles of the yellow triangle are the same as those of the outer triangle. From there I can work out the lengths of the sides of the blue triangles. However I don't know how to find the coordinates of the points of the blue triangles or the length of the sides of the yellow triangle and therefore the rectangles.
This is an X-Y problem (asking us how to accomplish X because you think it would help you solve a problem Y better solved another way), but luckily you gave us Y so I can just answer that.
What you should do is find the lines that are the edges of the roads, figure out where they intersect, and proceed to calculate everything else from that.
First, given 2 points P and Q, we can write down the line between them in parameterized form as f(t) = P + t(Q - P). Note that Q - P = v is the vector representing the direction of the line.
Second, given a vector v = (x_v, y_v) the vector (y_v, -x_v) is at right angles to it. Divide by its length sqrt(x_v**2 + y_v**2) and you have a unit vector at right angles to the first. Project P and Q a distance d along this vector, and you've got 2 points on a parallel line at distance d from your original line.
There are two such parallel lines. Given a point on the line and a point off of the line, the sign of the dot product of your normal vector with the vector between those two lines tells you whether you've found the parallel line on the same side as the other, or on the opposite side.
You just need to figure out where they intersect. But figuring out where lines P1 + t*v1 and P2 + s*v2 intersect can be done by setting up 2 equations in 2 variables and solving that. Which calculation you can carry out.
And now you have sufficient information to calculate the edges of the roads, which edges are inside, and every intersection in your diagram. Which lets you figure out anything else that you need.
Slightly different approach with a bit of trigonometry:
Define vectors
b = B - A
c = C - A
uB = Normalized(b)
uC = Normalized(c)
angle
Alpha = atan2(CrossProduct(b, c), DotProduct(b,c))
HalfA = Alpha / 2
HalfW = Width / 2
uB_Perp = (-uB.Y, ub.X) //unit vector, perpendicular to b
//now calculate points:
P1 = A + HalfW * (uB * ctg(HalfA) + uB_Perp) //outer blue triangle vertice
P2 = A + HalfW * (uB * ctg(HalfA) - uB_Perp) //inner blue triangle vertice, lies on bisector
(I did not consider extra case of too large width)
I have an n-sized collection of Rects, most of which intersect each other. I'd like to remove the intersections and reduce the intersecting Rects into smaller non-intersecting rects.
I could easily brute force a solution, but I'm looking for an efficient algorithm.
Here's a visualization:
Original:
Processed:
Ideally the method signature would look like this:
public static List<RectF> resolveIntersection(List<RectF> rects);
the output would be greater or equal to the input, where the output resolves the above visual representation.
Sweepline algoithms are good at processing intersections in 2D universes. I mean consider an horizontal line moving down from a rectangle edge to the next rectangle edge. The line hits a number of rectangles, forming the so-called active lists. The active list is kept updated at every move.
By studying the ranges of abscissas along the horizontal line, you can detect the overlaps.
A careful study of all configurations should allow you to split the rectangles the way you want in a single sweep, with lower complexity than brute force (closer to N^1.5 than to N^2).
this is a problem I solved in the past. The first thing it to sort the rectangles using the x or y value of one of the edges. Lets say you order in the y-direction and use the top edge. The topmost rectangle in your example is first in sorted order. For each rectangle you know its size in the y-direction.
Now, for each entry (call it the the current entry, it corresponds to a rectangle)in the sorted list you search forward through the list until you reach an entry greater than the current entry + the corresponding rectangle size. (call it the stopping entry)
Any entries in the sorted list between the current entry and this stopping entry will be potential intersections. Simply check if the rectangles x-ranges intersect.
When choosing to sort in the x or y direction, it will be better to choose the dimension that is larger as this will imply fewer intersection on average so less checking.
Here is an example. Rectangles are defined as R(x1,x2,y1,y2) where x1 is the left side, x2 is right side, y1 is top and y2 is bottom
rectangle 1 (1,5,0,4)
rectangle 2 (7,9,6,8)
rectangle 3 (2,4,2,3)
rectangle 4 (3,6,3,7)
rectangle 5 (3,6,9,15)
sort according to y1 to give
# y1 size
rectangle 1 0 4
rectangle 3 2 3
rectangle 4 3 4
rectangle 2 6 2
rectangle 5 9 6
so, rectangle 1 has y1 + size = 0 + 4 = 4 implying it will potentially intersect rectangle 3 (y1 value = 3 < 4) and rectangle 4 (y1 value = 3 < 4) but not rectangle 2 (y1 value = 6 > 4)...no need to check any rectangels in the list after 2
Rectangle 3 has y2 + size = 2 + 3 = 5 implying it will potentially intersect rectangle 4 (y1 value = 3 < 5) but not recatngle 2 (y1 value = 6 > 5) no need to check any rectangels in the list after 2
Rectangle 4 has y2 + size = 3 + 4 = 7 implying it will potentially intersect rectangle 2 (y1 value = 6 < 7) but not recatngle 5 (y1 value = 9 > 7)
Of course, with large numbers of rectangles you will generally only have to check a fraction of the possible pairs for intersection.
what you're descrbing is the packing problem, have a look at wikipedia
it refers to this article describing an algorithm for packing rectangles in rectangles
this is from the article:
This article describes a fast algorithm to pack a series of rectangles of varying widths and heights into a single enclosing rectangle, with no overlap and in a way that minimizes the amount of wasted space in the enclosing rectangle.
I need an idea for an algorithm to solve the following problem (I already tried some personal
solutions but they don't seem to be optimal)
If given a surface with marked and unmarked zones (in matrix form), and 2 rectangles
that you can manipulate in any form or position, find the possible shape and position
of the rectangles such that they cover all the marked zones while keeping the minimum
surface area possible.
This answer is assuming you can not rotate the rectangles and the sides are always parallel to the x and y axis.
First, find the rectangle that encloses the complete area. An algorithm for that goes like this (assuming the origin is at the topleft):
For each marked spot in the matrix:
if spot.x < rectangle.left:
rectangle.left = spot.x
if spot.x > rectangle.right:
rectangle.left = spot.x
if spot.y < rectangle.top:
rectangle.left = spot.x
if spot.y < rectangle.bottom:
rectangle.left = spot.x
Then, find the largest horizontal gap like this:
largest_gap = -1
For each column in matrix:
last_marked_spot = 0, 0
For each spot in column:
if spot.marked:
if spot.x - last_marked_spot.x > largest_gap:
largest_gap = spot.x - last_marked_spot.x
last_marked_spot = spot
Same goes for vertical gap. Then check which gap is the biggest.
Then divide the all-including rectangle in two parts using the biggest gap as seperator. The final step is to collapse the two rectangles (using the reverse of the algorithm on the top).
I've had this problem for a few years. It was on an informatics contest in my town a while back. I failed to solve it, and my teacher failed to solve it. I haven't met anyone who was able to solve it. Nobody I know knows the right way to give the answer, so I decided to post it here:
Ze problem
Given a rectangle, X by Y, find the minimum amount of circles N with a fixed given radius R, necessary to fully cover every part of the rectangle.
I have thought of ways to solve it, but I have nothing definite. If each circle defines an inner rectangle, then R^2 = Wi^2 + Hi^2, where Wi and Hi are the width and height of the practical area covered by each circle i. At first I thought I should make Wi equal to Wj for any i=j, the same for H. That way, I could simplify the problem by making the width/height ratios equal with the main rectangle (Wi/Hi = X/Y). That way, N=X/Wi. But that solution is surely wrong in case X greatly exceeds Y or vice versa.
The second idea was that Wi=Hi for any given i. That way, squares fill space most efficiently. However if a very narrow strip remains, it's much more optimal to use rectangles to fill it, or better yet - use rectangles for the last row before that too.
Then I realized that none of the ideas are the optimal, since I can always find better ways of doing it. It will always be close to final, but not final.
Edit
In some cases (large rectangle) joining hexagons seem to be a better solution than joining squares.
Further Edit
Here's a comparison of 2 methods: clover vs hexagonal. Hexagonal is, obviously, better, for large surfaces. I do think however that when the rectangle is small enough, rectangular method may be more efficient. It's a hunch. Now, in the picture you see 14 circles on the left, and 13 circles on the right. Though the surface differs much greater (double) than one circle. It's because on the left they overlap less, thus waste less surface.
The questions still remain:
Is the regular hexagon pattern itself optimal? Or certain adjustments should be made in parts of the main rectangle.
Are there reasons not to use regular shapes as "ultimate solution"?
Does this question even have an answer? :)
For X and Y large compared to R, a hexagonal (honeycomb) pattern is near optimal. The distance between the centers of the circles in the X-direction is sqrt(3)*R. The distance between rows in the Y-direction is 3*R/2, so you need roughly X*Y/R^2 * 2*/(3*sqrt(3)) circles.
If you use a square pattern, the horizontal distance is larger (2*R), but the vertical distance is much smaller (R), so you'd need about X*Y/R^2 * 1/2 circles. Since 2/(3*sqrt(3) < 1/2, the hexagonal pattern is the better deal.
Note that this is only an approximation. It is usually possible to jiggle the regular pattern a bit to make something fit where the standard pattern wouldn't. This is especially true if X and Y are small compared to R.
In terms of your specific questions:
The hexagonal pattern is an optimal covering of the entire plane. With X and Y finite, I would think it is often possible to get a better result. The trivial example is when the height is less than the radius. In that case you can move the circles in the one row further apart until the distance between the intersecting points of every pair of circles equals Y.
Having a regular pattern imposes additional restrictions on the solution, and so the optimal solution under those restrictions may not be optimal with those restrictions removed. In general, somewhat irregular patterns may be better (see the page linked to by mbeckish).
The examples on that same page are all specific solutions. The solutions with more circles resemble the hexagonal pattern somewhat. Still, there does not appear to be a closed-form solution.
This site attacks the problem from a slightly different angle: Given n unit circles, what is the largest square they can cover?
As you can see, as the number of circles changes, so does the covering pattern.
For your problem, I believe this implies: different rectangle dimensions and circle sizes will dictate different optimal covering patterns.
The hexagon is better than the diamond. Consider the percent area of the unit circle covered by each:
#!/usr/bin/env ruby
include Math
def diamond
# The distance from the center to a corner is the radius.
# On a unit circle, that is 1.
radius = 1
# The edge of the nested diamond is the hypotenuse of a
# right triangle whose legs are both radii.
edge = sqrt(radius ** 2 + radius ** 2)
# The area of the diamond is the square of the edge
edge ** 2
end
def hexagon
# The hexagon is composed of 6 equilateral triangles.
# Since the inner edges go from the center to a hexagon
# corner, their length is the radius (1).
radius = 1
# The base and height of an equilateral triangle whose
# edge is 'radius'.
base = radius
height = sin(PI / 3) * radius
# The area of said triangle
triangle_area = 0.5 * base * height
# The area of the hexagon is 6 such triangles
triangle_area * 6
end
def circle
radius = 1
PI * radius ** 2
end
puts "diamond == #{sprintf "%2.2f", (100 * diamond / circle)}%"
puts "hexagon == #{sprintf "%2.2f", (100 * hexagon / circle)}%"
And
$ ./geometrons.rb
diamond == 63.66%
hexagon == 82.70%
Further, regular hexagons are highest-vertex polygon that form a regular tessellation of the plane.
According my calculations the right answer is:
D=2*R; X >= 2*D, Y >= 2*D,
N = ceil(X/D) + ceil(Y/D) + 2*ceil(X/D)*ceil(Y/D)
In particular case if the remainder for X/D and Y/D equal to 0, then
N = (X + Y + X*Y/R)/D
Case 1: R = 1, X = 2, Y = 2, then N = 4
Case 2: R = 1, X = 4, Y = 6, then N = 17
Case 3: R = 1, X = 5, Y = 7, then N = 31
Hope it helps.
When the circles are disposed as a clover with four leafs with a fifth circle in the middle, a circle will cover an area equal to R * 2 * R. In this arrangement, the question becomes: how many circles that cover an area of R * 2 * R will cover an area of W * H?, or N * R * 2 * R = W * H. So N = W * H / R * 2 * R.