Length of an arc between two angles: Difference between revisions

From Rosetta Code
Content added Content deleted
(add FreeBASIC)
Line 195: Line 195:
first angle: 10.0000000 second angle: 120.000000 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
first angle: 180.000000 second angle: 270.000000 radius: 10.0000000 Length of major arc: 47.1238899
</pre>

=={{Header|FreeBASIC}}==

<lang freebasic>
#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)
</lang>
{{out}}
<pre>
43.63323129985824
</pre>
</pre>



Revision as of 20:27, 10 October 2020

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

Follows the Fortran interpretation of the task and finds the length of the major arc. <lang algolw>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.</lang>

Output:
   43.6332

AWK

<lang AWK>

  1. syntax: GAWK -f LENGTH_OF_AN_ARC_BETWEEN_TWO_ANGLES.AWK
  2. 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

Translation of: AWK

<lang c>

  1. define PI 3.14159265358979323846
  2. 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++

Translation of: Kotlin

<lang cpp>#include <iostream>

  1. define _USE_MATH_DEFINES
  2. 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

Translation of: C++

<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

Translation of: AWK

<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    

FreeBASIC

<lang freebasic>

  1. 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) </lang>

Output:
 43.63323129985824

Go

Translation of: Julia

<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

Translation of: AWK

<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

Translation of: Go

<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

Translation of: Raku

<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

Translation of: Julia

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

Python

<lang Python>import math

def arc_length(r, angleA, angleB):

   return (360.0 - abs(angleB - angleA)) * math.pi * r / 180.0


</lang>

radius = 10
angleA = 10
angleB = 120

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

Output:
43.63323129985823

Raku

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.

<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

Translation of: Julia

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

Translation of: C

<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

Translation of: Julia

<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

Translation of: Julia

<lang zkl>fcn arcLength(radius, angle1, angle2){

  (360.0 - (angle2 - angle1).abs()).toRad()*radius

} println(arcLength(10,10,120));</lang>

Output:
43.6332