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.
AWK
<lang AWK>
- syntax: GAWK -f LENGTH_OF_AN_ARC_BETWEEN_TWO_ANGLES.AWK
- converted from PHIX
BEGIN {
printf("%.7f\n",arc_length(10,10,120)) exit(0)
} function arc_length(radius,angle1,angle2) {
return (360 - abs(angle2-angle1)) * 3.14159265 / 180 * radius
} function abs(x) { if (x >= 0) { return x } else { return -x } } </lang>
- Output:
43.6332313
C
<lang c>
- define PI 3.14159265358979323846
- define ABS(x) (x<0?-x:x)
double arc_length(double radius, double angle1, double angle2) {
return (360 - ABS(angle2 - angle1)) * PI / 180 * radius;
}
void main() {
printf("%.7f\n",arc_length(10, 10, 120));
} </lang>
- Output:
43.6332313
C++
<lang cpp>#include <iostream>
- define _USE_MATH_DEFINES
- include <math.h>
double arcLength(double radius, double angle1, double angle2) {
return (360.0 - abs(angle2 - angle1)) * M_PI * radius / 180.0;
}
int main() {
auto al = arcLength(10.0, 10.0, 120.0); std::cout << "arc length: " << al << '\n'; return 0;
}</lang>
- Output:
arc length: 43.6332
D
<lang d>import std.math; import std.stdio;
double arcLength(double radius, double angle1, double angle2) {
return (360.0 - abs(angle2 - angle1)) * PI * radius / 180.0;
}
void main() {
writeln("arc length: ", arcLength(10.0, 10.0, 120.0));
}</lang>
- Output:
arc length: 43.6332
Delphi
<lang Delphi> program Length_of_an_arc;
{$APPTYPE CONSOLE} {$R *.res}
uses
System.SysUtils;
function arc_length(radius, angle1, angle2: Double): Double; begin
Result := (360 - abs(angle2 - angle1)) * PI / 180 * radius;
end;
begin
Writeln(Format('%.7f', [arc_length(10, 10, 120)])); Readln;
end. </lang>
- Output:
43.6332313
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
Fortran
The Fortran subroutine contains the MAX(DIF, 360. - DIF) operation. Other solutions presented here correspond to different interpretations of the problem. This subroutine computes the length of the major arc, which is not necessarily equal to distance traveling counter-clockwise. <lang fortran>*-----------------------------------------------------------------------
- given: polar coordinates of two points on a circle of known radius
- find: length of the major arc between these points
- ___Name_____Type___I/O___Description___________________________________
- RAD Real In Radius of circle, any unit of measure
- ANG1 Real In Angle of first point, degrees
- ANG2 Real In Angle of second point, degrees
- MAJARC Real Out Length of major arc, same units as RAD
- -----------------------------------------------------------------------
FUNCTION MAJARC (RAD, ANG1, ANG2) IMPLICIT NONE REAL RAD, ANG1, ANG2, MAJARC
REAL FACT ! degrees to radians PARAMETER (FACT = 3.1415926536 / 180.) REAL DIF
- Begin
MAJARC = 0. IF (RAD .LE. 0.) RETURN DIF = MOD(ABS(ANG1 - ANG2), 360.) ! cyclic difference DIF = MAX(DIF, 360. - DIF) ! choose the longer path MAJARC = RAD * DIF * FACT ! L = r theta RETURN END ! of majarc
- -----------------------------------------------------------------------
PROGRAM TMA IMPLICIT NONE INTEGER J REAL ANG1, ANG2, RAD, MAJARC, ALENG REAL DATARR(3,3) DATA DATARR / 120., 10., 10., $ 10., 120., 10., $ 180., 270., 10. /
DO J = 1, 3 ANG1 = DATARR(1,J) ANG2 = DATARR(2,J) RAD = DATARR(3,J) ALENG = MAJARC (RAD, ANG1, ANG2) PRINT *, 'first angle: ', ANG1, ' second angle: ', ANG2, $ ' radius: ', RAD, ' Length of major arc: ', ALENG END DO END
</lang>
- Output:
first angle: 120.000000 second angle: 10.0000000 radius: 10.0000000 Length of major arc: 43.6332321 first angle: 10.0000000 second angle: 120.000000 radius: 10.0000000 Length of major arc: 43.6332321 first angle: 180.000000 second angle: 270.000000 radius: 10.0000000 Length of major arc: 47.1238899
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
JavaScript
<lang JavaScript> function arc_length(radius, angle1, angle2) {
return (360 - Math.abs(angle2 - angle1)) * Math.PI / 180 * radius;
}
console.log(arc_length(10, 10, 120).toFixed(7)); </lang>
- Output:
43.6332313
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>
Kotlin
<lang scala>import kotlin.math.PI import kotlin.math.abs
fun arcLength(radius: Double, angle1: Double, angle2: Double): Double {
return (360.0 - abs(angle2 - angle1)) * PI * radius / 180.0
}
fun main() {
val al = arcLength(10.0, 10.0, 120.0) println("arc length: $al")
}</lang>
- Output:
arc length: 43.63323129985823
Perl
<lang perl>use strict; use warnings; use utf8; binmode STDOUT, ":utf8"; use POSIX 'fmod';
use constant π => 2 * atan2(1, 0); use constant τ => 2 * π;
sub d2r { $_[0] * τ / 360 }
sub arc {
my($a1, $a2, $r) = (d2r($_[0]), d2r($_[1]), $_[2]); my @a = map { fmod( ($_ + τ), τ) } ($a1, $a2); printf "Arc length: %8.5f Parameters: (%9.7f, %10.7f, %10.7f)\n", (fmod(($a[0]-$a[1] + τ), τ) * $r), $a2, $a1, $r;
}
arc(@$_) for
[ 10, 120, 10], [ 10, 120, 1], [120, 10, 1], [-90, 180, 10/π], [-90, 0, 10/π], [ 90, 0, 10/π];</lang>
- Output:
Arc length: 43.63323 Parameters: (2.0943951, 0.1745329, 10.0000000) Arc length: 43.63323 Parameters: (2.0943951, 0.1745329, 10.0000000) Arc length: 4.36332 Parameters: (2.0943951, 0.1745329, 1.0000000) Arc length: 1.91986 Parameters: (0.1745329, 2.0943951, 1.0000000) Arc length: 15.00000 Parameters: (0.0000000, -1.5707963, 3.1830989) Arc length: 5.00000 Parameters: (0.0000000, 1.5707963, 3.1830989)
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
Ring
<lang ring> decimals(7) pi = 3.14159265
see "Length of an arc between two angles:" + nl see arcLength(10,10,120) + nl
func arcLength(radius,angle1,angle2)
x = (360 - fabs(angle2-angle1)) * pi / 180 * radius return x
</lang>
- Output:
Length of an arc between two angles: 43.6332313
Ruby
<lang ruby>def arc_length(radius, angle1, angle2)
return (360.0 - (angle2 - angle1).abs) * Math::PI / 180.0 * radius
end
print "%.7f\n" % [arc_length(10, 10, 120)]</lang>
- Output:
43.6332313
Wren
<lang ecmascript>var arcLength = Fn.new { |r, angle1, angle2| (360 - (angle2 - angle1).abs) * Num.pi / 180 * r }
System.print(arcLength.call(10, 10, 120))</lang>
- Output:
43.633231299858
zkl
<lang zkl>fcn arcLength(radius, angle1, angle2){
(360.0 - (angle2 - angle1).abs()).toRad()*radius
} println(arcLength(10,10,120));</lang>
- Output:
43.6332