Length of an arc between two angles
Write a method (function, procedure etc.) in your language which calculates the length of the major arc of a circle of given radius between two angles.
- Task
In this diagram the major arc is colored green.
Illustrate the use of your method by calculating the length of the major arc of a circle of radius 10 units, between angles of 10 and 120 degrees.
Factor
<lang factor>USING: kernel math math.constants math.trig prettyprint ;
- arc-length ( radius angle angle -- x )
- abs deg>rad 2pi swap - * ;
10 10 120 arc-length .</lang>
- Output:
43.63323129985824
Go
<lang go>package main
import (
"fmt" "math"
)
func arcLength(radius, angle1, angle2 float64) float64 {
return (360 - math.Abs(angle2-angle1)) * math.Pi * radius / 180
}
func main() {
fmt.Println(arcLength(10, 10, 120))
}</lang>
- Output:
43.63323129985823
Julia
The task seems to be to find the distance along the circumference of the circle which is NOT swept out between the two angles. <lang julia> arclength(r, angle1, angle2) = (360 - abs(angle2 - angle1)) * π/180 * r @show arclength(10, 10, 120) # --> arclength(10, 10, 120) = 43.63323129985823 </lang>
Phix
<lang Phix>function arclength(atom r, angle1, angle2)
return (360 - abs(angle2 - angle1)) * PI/180 * r
end function ?arclength(10, 10, 120) -- 43.6332313</lang>
Raku
Taking a slightly different approach. Rather than the simplest thing that could possibly work, implements a reusable arc-length routine. Standard notation for angles has the zero to the right along an 'x' axis with a counter-clockwise rotation for increasing angles. This version follows convention and assumes the first given angle is "before" the second when rotating counter-clockwise. In order to return the major swept angle in the task example, you need to supply the "second" angle first. (The measurement will be from the first given angle counter-clockwise to the second.)
If you don't supply a radius, returns the radian arc angle which may then be multiplied by the radius to get actual circumferential length.
Works in radian angles by default but provides a postfix ° operator to convert degrees to radians and a postfix ᵍ to convert gradians to radians.
<lang perl6>sub arc ( Real \a1, Real \a2, :r(:$radius) = 1 ) {
( ([-] (a2, a1).map((* + τ) % τ)) + τ ) % τ × $radius
}
sub postfix:<°> (\d) { d × τ / 360 } sub postfix:<ᵍ> (\g) { g × τ / 400 }
say 'Task example: from 120° counter-clockwise to 10° with 10 unit radius'; say arc(:10radius, 120°, 10°), ' engineering units';
say "\nSome test examples:"; for \(120°, 10°), # radian magnitude (unit radius)
\(10°, 120°), # radian magnitude (unit radius) \(:radius(10/π), 180°, -90°), # 20 unit circumference for ease of comparison \(0°, -90°, :r(10/π),), # ↓ ↓ ↓ ↓ ↓ ↓ ↓ \(:radius(10/π), 0°, 90°), \(π/4, 7*π/4, :r(10/π)), \(175ᵍ, -45ᵍ, :r(10/π)) { # test gradian parameters printf "Arc length: %8s Parameters: %s\n", arc(|$_).round(.000001), $_.raku
}</lang>
- Output:
Task example: from 120° counter-clockwise to 10° with 10 unit radius 43.63323129985824 engineering units Some test examples: Arc length: 4.363323 Parameters: \(2.0943951023931953e0, 0.17453292519943295e0) Arc length: 1.919862 Parameters: \(0.17453292519943295e0, 2.0943951023931953e0) Arc length: 5 Parameters: \(3.141592653589793e0, -1.5707963267948966e0, :radius(3.183098861837907e0)) Arc length: 15 Parameters: \(0e0, -1.5707963267948966e0, :r(3.183098861837907e0)) Arc length: 5 Parameters: \(0e0, 1.5707963267948966e0, :radius(3.183098861837907e0)) Arc length: 15 Parameters: \(0.7853981633974483e0, 5.497787143782138e0, :r(3.183098861837907e0)) Arc length: 9 Parameters: \(2.7488935718910685e0, -0.7068583470577035e0, :r(3.183098861837907e0))
REXX
This REXX version handles angles (in degrees) that may be > 360º. <lang rexx>/*REXX program calculates the length of an arc between two angles (stated in degrees).*/ parse arg radius angle1 angle2 . /*obtain optional arguments from the CL*/ if radius== | radius=="," then radius= 10 /*Not specified? Then use the default.*/ if angle1== | angle1=="," then angle1= 10 /* " " " " " " */ if angle2== | angle2=="," then angle2= 120 /* " " " " " " */
say ' circle radius = ' radius say ' angle 1 = ' angle1"º" /*angles may be negative or > 360º.*/ say ' angle 2 = ' angle2"º" /* " " " " " " " */ say say ' arc length = ' arcLength(radius, angle1, angle2) exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ arcLength: procedure; parse arg r,a1,a2; #=360; return (#-abs(a1//#-a2//#)) * pi()/180 * r /*──────────────────────────────────────────────────────────────────────────────────────*/ pi: pi= 3.1415926535897932384626433832795; return pi /*use 32 digs (overkill).*/</lang>
- output when using the default inputs:
circle radius = 10 angle 1 = 10º angle 2 = 120º arc length = 43.6332313
zkl
<lang zkl>fcn arcLength(radius, angle1, angle2){
(360.0 - (angle2 - angle1).abs()).toRad()*radius
} println(arcLength(10,10,120));</lang>
- Output:
43.6332