Greenhouse Arc

Yesterday, I was reading posts on Gab and came across this post:

@DemsFearTruth:

Anyone good with math? I’m good with things up to a point, but I’ve not had to figure this type of math since HS.

Trying to figure out how to take a straight line and determine how tall it would be, if bent into an arch.

For example, if the width is 20 feet, and the pvc pipe is 40 feet in length, when bent into shape to arc from side to side of what will be a greenhouse, how tall will it be?

Like this, but bigger.

Or, if I wanted a 10 foot ceiling, how wide would it be?

I know how to do the math, it’s been so long since I did it, I can’t reactivate the memory engrams…

This tickled my fancy, so out came the pen and paper. An hour and a half later, I had an answer to the second question:

For a 40ft PVC pole bent such that the middle is 10ft above the ground, the length between the two ends will be 32 ft 3.46 in. The PVC pole is a 127 degree arc of a circle 36 feet in diameter.

Geometry

The first step in solving this is to find a mathematical concept that matches closely what we want to find, which in this case is the length across the ground of a curve of a given length when the midpoint of that curve is a fixed distance above the ground. The first thing that came to mind to approximate this is an arc of a circle.

Here is a diagram:

Greenhouse Arc Layout

In this diagram, l is the length of the pipe, h is the height above ground for the midpoint. What we want to know is c, the length of the chord formed by the endpoints of the pipe arc. The values we don’t know are the radius of the circle r, the angle of the arc ϴ and the distance below ground to the center of the circle a.

We can start getting some useful equations from this diagram. First, we can see the distance to the center of the circle from the ground is a = r - h. Math for circle arcs gives us the relationship l = r * ϴ (ϴ is in radians). We can rearrange this to get r = l / ϴ.

Trigonometry

Triangle

Next, we need to break out the trigonometry. If we look at one of the triangles with the side a, we can write the equation a = r * cos( 1/2 ϴ ). Next, a number of rearrangements and substitutions.

r cos( 1/2 ϴ ) = a					substitute a = r - h
r cos( 1/2 ϴ ) = r - h
cos( 1/2 ϴ ) = ( r - h ) / r
cos( 1/2 ϴ ) = 1 - h / r				substitute r = l / ϴ
cos( 1/2 ϴ ) = 1 - h / ( l / ϴ )
cos( 1/2 ϴ ) = 1 - ϴ ( h / l )				swap values
1 - cos( 1/2 ϴ ) = ϴ ( h / l )				Divide both sides by ϴ

[ 1 - cos( 1/2 ϴ ) ] / ϴ = h / l

0 = [ 1 - cos( 1/2 ϴ ) ] / ϴ - h / l

I got stuck here for a while trying to figure out how to solve for ϴ. Eventually I gave up and decided to use a different method: Newton’s Method

Numerical Methods

Newton’s method is a algorithm for solving for the root of an equation. A root is the value x where an equation f(x) = 0. The good thing about Newton’s method is you don’t have to rearrange the equation to solve for x. The downside is that it requires calculus and a lot of computations.

Newton’s Method

In Newton’s method, we calculate successively better guesses at the value we want. We need three things: the function we want to solve 0 = f(x) for, the derivative f’(x), and an initial guess for x. In cases where it is not possible or practical to get an exact equation for f’(x) a numerical approximation can be used, and I took this route.

Numerical Derivative

Using an initial guess of ϴ = π, this give me everything I need to solve for ϴ and then calculate the other values I am interested in. Because computers are excellent at repetitive calculations, I wrote a computer program to do the calculations for me. Below are both the code and the output. You can see the value of f(ϴ) getting progressively closer to zero as the program runs.

Code

h = 10.0
l = 40.0
TARGET = h / l

def f( theta )
	( 1 - Math.cos( 0.5 * theta ) ) / theta - TARGET
end

def f_diff( theta )
	e = 1e-6
	( f(theta+e) - f(theta-e) ) / e
end

theta = Math::PI
puts theta
30.times {
	theta = theta - f(theta) / f_diff(theta)
	puts "f(#{theta}) = #{f(theta)}"
}

puts "r = #{ r = l / theta }"
puts "c = #{ c = 2 * r * Math.sin( 0.5 * theta ) }"

Output

3.141592653589793
f(2.5510216203139615) = 0.027922763630872593
f(2.3733307473663046) = 0.013446819183550507
f(2.2935923873879434) = 0.006623777145277787
f(2.2554403763443736) = 0.0032895212091508252
f(2.2367452329754176) = 0.0016394421584128294
f(2.2274876984743113) = 0.0008184233399709528
f(2.2228808387670758) = 0.0004088910870729823
f(2.220582813192564) = 0.00020436587137845352
f(2.2194351425557537) = 0.00010216307636012889
f(2.2188616416697413) = 5.107658066572096e-05
f(2.218574974697218) = 2.553705187124944e-05
f(2.21843166206133) = 1.2768216431591206e-05
f(2.218360010953882) = 6.384030855510758e-06
f(2.21832418670251) = 3.1919960906678924e-06
f(2.218306274902358) = 1.5959932105902297e-06
f(2.218297319083672) = 7.979953969283748e-07
f(2.2182928411946734) = 3.98997396400258e-07
f(2.218290602255261) = 1.9949862278823005e-07
f(2.2182894827868247) = 9.974929254807918e-08
f(2.2182889230529246) = 4.987464152783616e-08
f(2.218288643186054) = 2.4937319653695056e-08
f(2.218288503252638) = 1.246865943826947e-08
f(2.218288433285936) = 6.2343296636235834e-09
f(2.218288398302586) = 3.1171648595673673e-09
f(2.218288380810911) = 1.5585824297836837e-09
f(2.2182883720650737) = 7.792911871362662e-10
f(2.218288367692155) = 3.8964564907928434e-10
f(2.2182883655056957) = 1.948228800507934e-10
f(2.218288364412466) = 9.741141226982108e-11
f(2.218288363865851) = 4.870570613491054e-11
r = 18.03192075997337
c = 32.28859955035297

Notes

  1. For the curious, the software I used to make the diagram is LibreCAD and Inkscape.

Comments