How do I connect N circles of the same diameter tangentially? - algorithm

If I have N number of circles all with the same diameter, how do I determine the minimum inscribed polygon that will connect them tangentially? Is there a formula to do this?
Once that polygon is created, I believe a circle will be placed at the midpoint of each line segment.
A few examples of what I'm going for in pictures: https://imgur.com/a/J9lt89P

Place circle centers at positions relative common center:
R = r / Sin(Pi/N)
coordinates for i-th circle center:
cx(i) = R * Cos(i * 2 * Pi / N)
cy(i) = R * Sin(i * 2 * Pi / N)
where N is number of circles, r is circle radius

Related

Formula, Circle's perimeter intersects with corners of rectangle

Note: Everything about the circle is unknown. Only the width and height of the rectangle are known.
I devised a formula to determine the diameter of circle, so that the circle's perimeter intersects with the bottom two corners of a rectangle, whatever the proportion of the rectangle is (or at least if the width is greater than the height). The formula is as follows, whereby W refers to the width and H refers to the height of the rectangle:
X = W / H
Diameter = ((X/4) + (1/X)) * W
Does anybody know a more eloquent way to calculate this or is there a known algorithm to do this more efficiently?
Letting the center of the circle be (0, 0), the diameter be D, the width of the rectangle be W, and the height be H, the points (±W/2, D/2 − H) should lie on the circle, which by Pythagoras holds if and only if
(W/2)2 + (D/2 − H)2 = (D/2)2.
Expanding the binomial and subtracting (D/2)2 from both sides, we get
W2/4 − D H + H2 = 0.
Solving for D by adding D H to both sides and dividing through by H, we get
D = W2/(4 H) + H.
In code this could be as follows.
double diameter(double width, double height) {
return width * width / (4 * height) + height;
}

Find evenly distributed random points on a spherical cap

I have a latitude, longitude and radius of 400m-1000m forming a spherical cap. I need to find a random point on that cap. The points must be evenly distributed over the area.
There is a related question about finding random points in a circle. My first thought was to project the cap on to a Cartesian plane and using the circle algorithm. The radius is small enough that there should be no important level of error.
I'm not sure if projecting and then converting the point back to a lat/lng is the simplest solution or what other possible solutions there are to this problem
You can generate random azimuth in range 0..360 and random distance with sqrt-distribution to provide unifrom distribution
d = maxR * Sqrt(random(0..1))
theta = random(0..1) * 2 * Pi
Then get geopoint coordinates using bearing and distance as described here (Destination point given distance and bearing from start point)
φ2 = asin( sin φ1 ⋅ cos δ + cos φ1 ⋅ sin δ ⋅ cos θ )
λ2 = λ1 + atan2( sin θ ⋅ sin δ ⋅ cos φ1, cos δ − sin φ1 ⋅ sin φ2 )
where φ is latitude, λ is longitude, θ is the bearing
(clockwise from north), δ is the angular distance d/R;
d being the distance travelled, R the earth’s radius
As mentioned in the wiki page theta + phi = 90 if phi is a latitude. On the other hand, as r is fixed for all points on the cap, we just need set the value of the theta. Hence, you can pick a random value from 0 to theta value (related to the cap) and define the point by the explained constraints.
For a disc very small compared to the radius of the sphere the lat-long projection will simply be approximately an ellipse except when you are very close to poles.
First compute the stretch at the given latitude:
double k = cos(latitude * PI / 180);
then compute the disc radius in latitude degrees
// A latitude arc-second is 30.87 meters
double R = radius / 30.87 / 3600 * PI / 180;
then compute a uniform random point in a circle
double a = random() * 2 * PI;
double r = R * sqrt(random());
your random point in the disc will be
double random_lat = (latitude*PI/180 + r*cos(a))/PI*180;
double random_longitude = (longitude*PI/180 + (r/k)*sin(a))/PI*180;

Find an optimal n square size (same for each) to fit most part of rectangle container

Input
Rectangle area width and height, so we could calculate rectangle aspect/proportions.
N is the number of squares that we want to resize using the same size for each.
Output
Find the optimal squares size that would fit most part of our container. For example
containerWidth = 200;
containerHeight = 100;
n = 8;
In this case squaresSize should be 50 to fit most of rectangle area.
What i tried
I already tried to calculate container math area and then divide it to the number of squares to get each square area by taking a square root. But this is the ideal square size, so it douesn't respect each square place relative to container rectangle.
Real purpouse
I trying to make scallable user interface, that would draw as much square objects in rectangle container as it is possible.
You have to solve inequality (find max value of a)
(Width div a) * (Height div a) >= n
where div is integer division with truncation (8 div 3 = 2)
Result depends monotonically on n, so get first approximation as
a = Sqrt(W*H/n)
and find exact value with linear or binary search
Let S be the size of each square (width and height). Then you want to solve the optimization problem
maximize S
subject to floor(Width / S) * floor(Height / S) >= n
S >= 0
The feasible region is a range [0, S*], where S* is the optimal solution.
We know that S * S * n <= Width * Height for all feasible S; that is, S <= sqrt(Width * Height / n).
So you can simply binary search the range [0, sqrt(Width * Height / n)] for the largest value of S for which floor(Width / S) * floor(Height / S) >= n.
Once you have the optimal S*, you will place your squares into the container in a grid with floor(Width / S*) columns and floor(Height / S*) rows.

Maximum surface inside a triangle

I have encountered the following interesting problem while preparing for a
contest.
You have a triangle with sides of length a, b, c and a rope of length L. You need to find
the surfaced enclosed by the rope that has the maximum surface area and it has to be entirely inside the triangle.
So, if L = a + b + c, then it's the area of the triangle.
Else, we know that the circle has the biggest surface to perimeter area, so if L is smaller or equal to the perimeter of the inscribed circle of the triangle, then the area will be the area of the circle of perimeter L.
So, the remaining case is alfa < L < a + b + c, where alfa is the perimeter of the inscribed circle .
Any ideas would be great!
EDIT: I would like to know if I should focus on some kind of algorithm for solving this
or trying to figure it out a mathematical formula. The contest contains somehow a combination of both. The edges can be as long as 100 and the precision of a,b,c,L is of 4 digits after the decimal point .
After reading the answers to this question: https://math.stackexchange.com/questions/4808/why-circle-encloses-largest-area, I agree with n.m., and think the optimal curve verifies:
Curvature is either constant, or flat when it touches the triangle, meaning it is composed of segments lying on the triangle sides, and circle arcs, all sharing the same radius.
There are no angles, meaning the arcs are tangent to the triangle sides.
With these conditions, the solution is obtained by three circles of same radius R, each tangent to two sides of the triangle (see below). When R varies between 0 and the radius of the inscribed circle, we start from the triangle itself, and end to the inscribed circle, where all three circles coincide. The length of the curve is the perimeter of the circle of radius R + the perimeter (p) of the smaller triangle: L = 2*PiR + p. The area is the area (a) of the smaller triangle + one disc of radius R + the remaining rectangles: A = PiR^2 + p*R + a.
Since a circle has the largest Area/Perimeter, start with the inscribed circle. If L is less than that circumference, then shrink appropriately. If L is longer, grow whichever of the 3 arcs maximizes dA/dL. I don't know if there's a closed form, but the largest arc will be in the 3rd of the triangle with the sides most approaching parallel.
It should be trivial to solve this algorithmically. With 4 decimals of precision, increment by 0.0001 checking each arc to see which has the greatest dA/dL for that single increment.
I worked up a drawing of the geometry overnight:
The inscribed circle is constructed by bisecting each of the angles and finding the intersections of the bisectors. I've labeled the half-angle "a1" (and all related variables have '1'). The area of the non-circular portion is two trapezoids (one denoted with the red outline). We can calculate the area for a single trapezoid as L1 * (m1 + R)/2 (note that when L1, L2, L3 are all zero, these trapezoids are all zero, and we just get the inscribed circle area). The circular cap has a radius of m1 to remain tangent with the side of the triangle. For a given choice of L1, m1 = R(x1-L1)/x1.
From here you can easily calculate the perimeter and area of each of the three sectors and solve numerically.
I cannot prove that this is the largest area, just that this is how to calculate the area and perimeter of this construction.
..answering my own comment/question, it can be proved that the radii must be equal,
Here is a useful formula:
the gray area A is
A = r^2 ( alpha - Pi + 2/tan(alpha/2) ) /2
but even more useful..the arc length is simply:
s = 2 ( b - A/r )
from here it is straightforward to show the three radii must be equal to each other:
writing the rope length and enclosed area:
ropelength = trianglelength - 2 Sum[r[i] a[i] ]
ropearea = trianglearea - Sum[r[i]^2 a[i] /2 ]
where
a[i]=( alpha[i] - Pi + 2/tan(alpha[i]/2) )
after a bit of manipulation maximizing the area leads to all r[i] equal. Note the three a[i], ropelength,trainglearea,trianglelength are all constants that you do not need to work out. Pedantically solve for r[l] = f( constants, r[2],r[3] ) sub into the second expression and solve for d ropearea /d r[2] = 0 and d /d r[3] = 0 with the result:
r =(1/2) (triangle_length - rope_length) /(Sum(1/tan(alpha[i]/2)) - Pi)
(the messy expression for a[i] is substituted only at the last step ) finally..
ropearea = trianglearea - (trianglelength-ropelength)^2/(8 Sum[a[i])
= trianglearea - (1/2)(trianglelength-ropelength) r
edit -- a useful identity ..with a,b,c, the lengths of the sides.
Sum(1/tan(alpha[i]/2)) = Sqrt( S^3 / ((S-a)(S-b)(S-c)) )
S = 1/2 (a+b+c) ! S is semiperimeter not to be confused with arc length s
the above expressions then can be used to reproduce the formula for an inscribed circle,
rinscribed = Sqrt( ((S-a)(S-b)(S-c)) / S )
If the perimeter of the rope is too small or too large, the answers are trivial. The interesting case is a shape with 6 vertices that goes line-arc-line-arc-line-arc. The arc are all tangent to their neighbouring lines and their radii are equal. I don't have a rigorous proof, but imagine a 2D balloon filled with air and squeezed between the sides of the triangle.
It is easy to express the overall shape and thus the perimeter given the radius; the opposite direction (perimeter to radius) is then easily found numerically.

Algorithm to find minimum no.of sides of a polygon

How to design an algorithm to find minimum no.of sides of a polygon which lies between two concentric circles?
Similar to this:
Think about the simplest case first: the inner circle is microscopically small. The minimum number of sides is 3, as long as the inner circle has a non-zero radius.
When does the polygon start needing 4 sides? Draw an equilateral triangle inscribed in the circle. The polygon starts needing 4 sides when the inner circle's radius reaches the center point of the sides of the triangle.
If you inscribe a regular polygon of N sides into the outer circle, you can compute the distance from the midpoint of each side to the center of the circle using the cosine rule:
distance_to_midpoint = cos ( 360 / (N * 2) ) * radius_of_outer_circle
(Explanation: if you make a isosceles triangle using the center point of the circle to the side in question, the radii have an angle of 360 / N. Divide the triangle in half at the side's midpoint to form a right-angle triangle with hypotenuse equal to the radius of the outer circle, then use cosine rule)
Now distance_to_midpoint needs to be greater than or equal to the radius of the inner circle, so solve for N:
radius_of_inner_circle = cos(360 / (N * 2)) * radius_of_outer_circle
cos(360 / (N*2)) = radius_of_inner_circle / radius_of_outer_circle
360 / (N*2) = acos(radius_i / radius_o)
N = 180 / (acos(radius_i / radius_o))
(I haven't double checked this math, and it's really late).
Denote the radius of the polygon, which is the radius of the circumcircle of the polygon, by R. The radius of the inscribed circle is
r = R*Cos[180°/n]
Solve this for n, eliminate the spurious solution which gives a negative result, and you have
n = 180°/ArcCos[r/R]
You'll have to fiddle around a bit to get an integer value for n, I'll leave that to you.
Draw a tangent to the inner circle, mark A, B - intersections of the tangent with the outer circle.
Draw a tangent (different) to the inner circle from point B, mark the intersection with outer circle C.
Repeat the procedure (2) until the new tangent crosses first tangent AB.
This algorithm will ensure you cover the maximum radial section at each step, thus minimizing the number of sides in the resulting polygon.
If you only want to find number of sides, it's enough to find an angle between 2 tangents to the inner circle coming from the same point on the outer circle and calculate how many such angles comprise the full 360 degrees (add 1 if there is a remainder) - like #cheeken suggested in comment

Resources