I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Length of an arc between two angles

From Rosetta Code
Length of an arc between two angles is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

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.

In this diagram the major arc is colored green   (note: this website leaves cookies).

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.


ALGOL W[edit]

Follows the Fortran interpretation of the task and finds the length of the major arc.

begin
 % returns the length of the arc between the angles a and b on a circle of radius r %
 % the angles should be specified in degrees  %
real procedure majorArcLength( real value a, b, r ) ;
begin
real angle;
angle := abs( a - b );
while angle > 360 do angle := angle - 360;
if angle < 180 then angle := 360 - angle;
( r * angle * PI ) / 180
end majorArcLength ;
 % task test case  %
write( r_w := 10, r_d := 4, r_format := "A", majorArcLength( 10, 120, 10 ) )
end.
Output:
   43.6332

AWK[edit]

 
# 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 } }
 
Output:
43.6332313

C[edit]

Translation of: AWK
 
#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));
}
 
Output:
43.6332313

C++[edit]

Translation of: Kotlin
#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;
}
Output:
arc length: 43.6332

D[edit]

Translation of: C++
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));
}
Output:
arc length: 43.6332

Delphi[edit]

Translation of: AWK
 
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.
 
Output:
43.6332313

Factor[edit]

USING: kernel math math.constants math.trig prettyprint ;
 
: arc-length ( radius angle angle -- x )
- abs deg>rad 2pi swap - * ;
 
10 10 120 arc-length .
Output:
43.63323129985824

Fortran[edit]

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.

*-----------------------------------------------------------------------
* 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
 
 
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    

FreeBASIC[edit]

 
#define DEG 0.017453292519943295769236907684886127134
 
function arclength( r as double, a1 as double, a2 as double ) as double
return (360 - abs(a2 - a1)) * DEG * r
end function
 
print arclength(10, 10, 120)
 
Output:
 43.63323129985824

Go[edit]

Translation of: Julia
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))
}
Output:
43.63323129985823

Java[edit]

public static double arcLength(double r, double a1, double a2){
return (360.0 - Math.abs(a2-a1))*Math.PI/180.0 * r;
}

JavaScript[edit]

Translation of: AWK
 
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));
 
Output:
43.6332313

Julia[edit]

The task seems to be to find the distance along the circumference of the circle which is NOT swept out between the two angles.

 
arclength(r, angle1, angle2) = (360 - abs(angle2 - angle1)) * π/180 * r
@show arclength(10, 10, 120) # --> arclength(10, 10, 120) = 43.63323129985823
 

Kotlin[edit]

Translation of: Go
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")
}
Output:
arc length: 43.63323129985823

Perl[edit]

Translation of: Raku
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/π];
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[edit]

Translation of: Julia
function arclength(atom r, angle1, angle2)
return (360 - abs(angle2 - angle1)) * PI/180 * r
end function
?arclength(10, 10, 120) -- 43.6332313

Python[edit]

import math
 
def arc_length(r, angleA, angleB):
return (360.0 - abs(angleB - angleA)) * math.pi * r / 180.0
 
 
 
radius = 10
angleA = 10
angleB = 120

result = arc_length(radius, angleA, angleB)
print(result)

Output:
43.63323129985823

Raku[edit]

Works with: Rakudo version 2020.02

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.

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
}
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[edit]

Translation of: Julia

This REXX version handles angles (in degrees) that may be   >   360º.

/*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).*/
output   when using the default inputs:
     circle radius =  10
           angle 1 =  10º
           angle 2 =  120º

        arc length =  43.6332313

Ring[edit]

 
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
 
Output:
Length of an arc between two angles:
43.6332313

Ruby[edit]

Translation of: C
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)]
Output:
43.6332313

Wren[edit]

Translation of: Julia
var arcLength = Fn.new { |r, angle1, angle2| (360 - (angle2 - angle1).abs) * Num.pi / 180 * r }
 
System.print(arcLength.call(10, 10, 120))
Output:
43.633231299858

zkl[edit]

Translation of: Julia
fcn arcLength(radius, angle1, angle2){
(360.0 - (angle2 - angle1).abs()).toRad()*radius
}
println(arcLength(10,10,120));
Output:
43.6332