#degree #circle #angle #modular-arithmetic #gis #64-bit #longitude

ring360

用于表示圆周上64位浮点数的简单封装类型。它具有加法和减法运算符重载,计算最短角度并实现核心三角函数。

2 个版本

0.2.13 2024年8月11日
0.2.12 2024年6月12日
0.2.11 2024年4月14日
0.2.10 2024年3月21日
0.1.0 2024年2月25日

#199 in 数学

Download history 5/week @ 2024-05-20 166/week @ 2024-06-10 4/week @ 2024-06-17 47/week @ 2024-07-01 51/week @ 2024-07-29 63/week @ 2024-08-05 65/week @ 2024-08-12

每月下载量:179
用于 aspect360

GPL-2.0-or-later WITH Bison-exception-2…

19KB
145

mirror crates.io docs.rs

Ring360:360度圆周上的模运算

此crate提供了一个用于表示二维圆周上64位浮点数的简单封装结构体。该类型允许您使用加法和减法运算符(+ 和 -)进行操作,并计算两个角度之间的最短角度。乘法和除法仅通过 multiply() 和 divide() 方法与原始 float-64 值一起工作。

Ring360 类型是一个简单的元组结构体,封装了原始 f64 值,并提供方法来公开其 degrees()、rotations() 或原始值(),例如 Ring360(400.0) 将具有原始值 400.0,但以度为 40°,1 次旋转。

由于此数据类型在 360° 圆周上工作,因此负原始值会产生相反方向的正度数,例如 -60° 是 300°。地球圆周上的经度通常以 ±180° 表示。在这种情况下,0° 到 180° 之间的经度相同,但 180° 到 360° 之间的经度从 -180° 下降到 0°。这意味着 ±180 系统中的 -120° 在 360° 系统中是 240°。为此,crate 提供了从和到 GIS ±180 系统的转换方法,即 value_f64.to_360_gis() 或 Ring360_from_gis(lng180: f64)。这种转换不会改变实际的度数,因为 ±180° 系统中的 -60° 本身就会转换为 300°,但它会影响旋转次数。请注意,一些地理信息系统(例如 QGIS)使用 360° 系统并且因此使用标准 to_360() 和 degrees() 方法。

添加和减去度数值

/// Add and/or subtract degrees on a circle
/// The degree value represents the longitude, while the intrinsic f64 value 
/// represents the angle travelled around the circumference
let longitude_1 = 74.7.to_360(); // or Ring360(74.7);
let longitude_2 = 291.4.to_360();
let longitude_3 = 126.1.to_360();

let result_1 = longitude_1 + longitude_2 + longitude_3;

println!(
  "Degrees: {:.1}º, intrinsic value is {:.1}, rotations: {}",
  result_1.degrees(),
  result_1.value(),
  result_1.rotations()
);
/// Should read: Degrees: 132.2º, intrinsic value is 492.2, rotations: 1

let result_2 = longitude_1 - longitude_2 + longitude_3;

println!("Degree value: {}º", result_2);
/// Should read: Degree value: 269.4º

使用 ±180 GIS 系统,-180° 到 180°

/// Declare two degrees on the GIS scale
let gis_lng_1 = 143.32;
let gis_lng_2 = -111.4;

/// Shift ±180 degrees to a 0º to 360º scale
let lng_360_1 = gis_lng_1.to_360_gis(); // or Ring360::rom_gis(74.7);
let lng_360_2 = gis_lng_2.to_360_gis();

let angle_3 = lng_360_1.angle(lng_360_2);

println!("The longitudinal distance between {} and {} is {}", lng_360_1.to_gis(), lng_360_2.to_gis(), angle_3);
/// The longitudinal distance between 143.32 and -111.4 is 105.28

从和到 f64 的转换

let value_1 = 74.7;
let value_2 = 291.4;

let longitude_1 = value_1.to_360();
let longitude_2 = value_2.to_360();

let result_1_f64 = (longitude_1 + longitude_2).degrees();

println!(
  "{}º +  {}º equals {}º",
  longitude_1,
  longitude_2,
  result_1_f64
);

乘法和除法

这些操作不是直接为 Ring360 值中的度数实现的,而是仅通过 multiply() 和 divide() 方法与原始 f64 值一起工作。

let value_1 = 74.7;
let factor = 4.0;

let result_1 = value_1.to_360().multiply(factor);

println!(
  "{}º multiplied by {} equals {}º",
  value_1,
  factor,
  result_1
);

let result_2 = value_1.to_360().divide(factor);

println!(
  "{}º divided by {} equals {}",
  value_1,
  factor,
  result_2
);

角度距离

《angle()`》和《angle_f64()`》方法计算圆周上两点经度之间最短的角度(以度为单位)。负值表示从A到B的逆时针偏移,例如从340°到320°是负值,而350°到10°是正值。

let value_1 = 297.4;
let longitude_1 = value_1.to_360();
let value_2: f64 = 36.2;
let longitude_2 = value_2.to_360();

let result_1 = longitude_1.angle(longitude_2);

let result_2 = longitude_1.angle_f64(value_2);

println!(
  "Both results should be the same: {} == {}",
  result_2,
  result_1
);

绝对无方向角度

《angle_abs()`》和《angle_f64_abs()`》方法计算圆周上两点经度之间顺时针方向的绝对角度(以度为单位)。超过180.0的值表示超过半圈。对于《f64》值,您可以使用《.angle_360_abs(other_value: f64)`>方法。

let value_1 = 270.0;
let longitude_1 = value_1.to_360();
let value_2: f64 = 30.0;
let longitude_2 = value_2.to_360();

let result_1 = longitude_1.angle_abs(longitude_2);
let result_2 = longitude_2.angle_abs(longitude_1);

println!(
  "The angles may be anywhere in the 0 to 359.9999º range: {} and {}",
  result_2,
  result_1
);

直接计算正弦、余弦和正切

let value_1 = 45.0;
  let degree_1 = value_1.to_360();

println!(
  "The sine of {}º is {:.12}",
  degree_1.degrees(),
  degree_1.sin()
);
// Should print: The sine of 45º is 0.707106781187

let value_2 = 60.0;
let degree_2 = value_2.to_360();

println!(
  "The cosine of {}º is {:.1}",
  degree_2.degrees(),
  degree_2.cos()
);
// Should print: The cosine of 60º is 0.5

实例方法

  • degrees()-> f64 从0°到360°的度数值。
  • to_f64() -> f64 degrees()的别名和默认显示值
  • to_gis() -> f64 将内部0-360°刻度转换为-180°到+180°的GIS刻度
  • rotations() -> i64 达到当前原始值所需的旋转次数,例如730.0需要2次旋转,度数为10.0。
  • progress() -> f64 圆周上表示为小数分数的内在值,即180°等于0.5,450°等于1.25
  • value() -> f64 原始f64值
  • as_tuple() -> (f64, i64) 返回一个包含度数(f64)和旋转次数(i64)的元组
  • multiply(multiple: f64) -> Self 将Ring360值乘以常规f64值
  • divide(divisor: f64) -> Self 将Ring360除以常规f64值
  • angle_f64(other_value: f64) -> f64 计算Ring360值与表示度数的64位浮点数之间的最短距离(以度为单位)。正值表示第一个经度和第二个经度之间的顺时针移动
  • angle(other_value: Ring360) -> f64 两个Ring360值之间的角距离
  • to_radians() -> f64 转换为弧度以实现互操作性
  • sin() -> f64 正弦(隐式弧度转换,例如30.to_360().sin()返回0.5)
  • cos() -> f64 余弦
  • tan() -> f64 正切
  • asin() -> f64 反正弦
  • acos() -> f64 反余弦
  • atan() -> f64 反正切

静态方法

  • half_turn() -> f64 360°基础的一半,即180.0

常量

  • BASE:f64 = 360.0

特质

ToRing360

此实现仅适用于f64,具有以下方法

  • to_360() -> Ring360 将任何表示360°系统的64位浮点度数转换为Ring360值;
  • to_360_gis() -> Ring360 将任何表示±180°系统的64位浮点度数转换为Ring360值并规范化到0-360°刻度。
  • mod_360() -> f64 一个方便的方法用于% 360.0,但将负值视为反向的正度数,例如(-20.0).mod_360等于340°
  • angle_360(other_value: f64) -> f64:计算两个f64值之间的最短角度(以度为单位)。
  • angle_360_abs(other_value: f64) -> f64:计算两个f64值之间的绝对无方向角度(以度为单位)。

开发说明

此软件包正在开发中,但实现了所有核心功能。

版本说明

0.2.11

  • angle_abs() -> f64 返回绝对无方向角度,与相关的angle_f64_abs()angle_360_abs()方法相关

0.2.8

  • progress() -> f64 返回围绕圆的十进制进度旋转

0.2.6

以下方法已添加到 Ring360

  • to_radians() 用于与其他数学函数兼容

核心三角方法 sin(), cos(), tan(), asin(), acos() 和 atan() 是从度数计算得出的,无需显式转换为弧度

  • .sin() -> f64 计算正弦
  • .cos() -> f64 计算余弦
  • .tan() -> f64 计算正切
  • .asin() -> f64 计算反正弦(反正弦,asin)
  • .acos() -> f64 计算反余弦(反余弦,acos)
  • .atan() -> f64 计算反正切(反正切,atan)

0.2.5

以下过时方法已在版本 0.2.5 中删除

  • degree() => 使用 degrees() 代替。
  • turns() => 使用 rotations() 代替。

0.2.10

  • 已删除过时的 Ring360::from_180(-90.0) 构造函数和 Ring360.to_180() 方法。请使用 Ring360::from_gis(-90.0)Ring360.to_360_gis() 代替。注意:这不会影响计算的 360 度值。它只会影响计算的旋转次数,其中 -30 在 to_360() 和 to_360_gis() 中都转换为 330 度,但使用默认的转换方法时旋转次数为 -1,而使用 f64.to_360_gis() 时为 0。

0.2.12

  • 简化了 ring360 的 angle_f64() 方法,并添加了一个新的静态方法 minus_half_turn() (-180)。

没有运行时依赖