marcoconsiglio/goniometry 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

marcoconsiglio/goniometry

Composer 安装命令:

composer require marcoconsiglio/goniometry

包简介

A PHP support for string, decimal, radian and object angles, providing goniometric algebra and comparison between angles.

README 文档

README

GitHub License GitHub Release Static Badge

Static Badge Static Badge Static Badge

A PHP support for string, decimal, radian and object angles, providing goniometric algebra and comparison between angles.

Index

Requirements

Installation

composer require marcoconsiglio/goniometry

Quick Start

Import this class to represent angles.

use MarcoConsiglio\Goniometry\Angle;

Create an Angle object (-360°/+360°).

$alfa = Angle::createFromValues(180, 30);
$beta = Angle::createFromString("180° 30'");
$gamma = Angle::createFromDecimal(180.5);
$delta = Angle::createFromRadian(M_PI); // 180°

Create an AngularDistance object (-180°/+180°).

$alfa = AngularDistance::createFromValues(180, 30);
$beta = AngularDistance::createFromString("180° 30'");
$gamma = AngularDistance::createFromDecimal(180.5);
$delta = AngularDistance::createFromRadian(M_PI); // 180°

Both Angle and AngularDistance are AngularMeasure types that implement the Angle interface.

Usage

Creating an AngularMeasure object

Sexagesimal (int degrees, int minutes, float seconds)

This creates an angle from its values in degrees, minutes and seconds:

$alfa = Angle::createFromValues(180, 12, 43.4618, Rotation::CLOCKWISE); // -180° 12' 43.4618"

Rotation::COUNTER_CLOCKWISE is the plus sign, Rotation::CLOCKWISE is the minus sign.

A null angle (exactly $0^\circ\space0'\space0"$) will always have a Rotation::COUNTER_CLOCKWISE.

Sexagesimal (string)

This creates an angle from its textual representation:

$beta = Angle::createFromString("-180° 12' 43.4618\"");

This is possible thanks to the regular expressions

Angle::DEGREES_REGEX;
Angle::MINUTES_REGEX;
Angle::SECONDS_REGEX;

These regex expressions treat degrees and minutes as int type, but seconds are treated as a float type.

You can create a negative Angle if the string representation start with the minus (-) sign.

The NoMatchException is thrown when you try to create an AngularMeasure with a bad formatted string.

Sexadecimal (float)

This create an angle from its decimal representation:

$gamma = Angle::createFromDecimal(180.2119);   //  180.2119°
$gamma = Angle::createFromDecimal(-180.2119);  // -180.2119°
$gamma = Angle::createFromDecimal(301.0);      //    1.0°

Radian (float)

This create an angle from its radian representation:

$delta = Angle::createFromRadian(M_PI);      //  π ≅  180°
$delta = Angle::createFromRadian(
  new Radian(Number::π())
);                                           //  π =  180°
$delta = Angle::createFromRadian(-M_PI);     // -π ≅ -180°
$delta = Angle::createFromRadian(2 * M_PI);  // 2π ≅    0°

If you need a precise $\pi$ value, you can pass a Radian object constructed with the Number::π() static method that return the π constant with an arbitrary precision up to 54 digits.

The Radian class extend the ModularNumber class, whose API is documented in marcoconsiglio/modular-arithmetic.

For more info on Number::π() check the API of marcoconsiglio/bcmath-extended.

Getting angle values

You can obtain sexagesimal values separated in an array (simple by default, or associative):

$values = $alfa->getDegrees();
echo $values[0]; // int
echo $values[1]; // int
echo $values[2]; // float
$values = $alfa->getDegrees(true);
echo $value['degrees']; // int
echo $value['minutes']; // int
echo $value['seconds']; // float

The angle's direction determines the sign of the degrees value.

There are read-only properties too:

/** @var Degrees */
(string) $alfa->degrees;  // 180°
/** @var Minutes */
(string) $alfa->minutes;  // 12'
/** @var Seconds */
(string) $alfa->seconds;  // 43"
/** @var Rotation */
$alfa->direction;         // Rotation::CLOCKWISE (-1)

The Degrees and Minutes to int, and Seconds to float. These three classes extends ModularNumber, whose API is documented in marcoconsiglio/modular-arithmetic.

You can cast Degrees, Minutes, and Seconds to string automatically putting their variables in a string.

Rotation direction

Positive angles are represented by the enum constant

Rotation::COUNTER_CLOCKWISE; // 1

while negative angles are represented by the opposite enum constant:

Rotation::CLOCKWISE; // -1

You can toggle the rotation direction:

$beta = $alfa->oppositeRotation();

Since the Angle instance is immutable, the toggleRotation() method returns a copy with the opposite sign.

You can check if an Angle is clockwise or counterclockwise.

// If $alfa is a positive angle
$alfa->isCounterClockwise();    // true
$alfa->isClockwise();           // false
// If $beta is a negative angle
$beta->isCounterClockwise();    // false
$beta->isClockwise();           // true

Opposite direction

You can calc the opposite direction of an AngulaMeasure interface with the method oppositeDirection().

$alfa = Angle::createFromDecimal(90.0);
$beta = $alfa->oppositeDirection();
(string) $beta; // 180° 0' 0"

Absolute value

The absolute() method return a copy of the AngularMeasure without the negative sign.

$negative_angle = Angle::createFromDecimal(-180); // -180°
$positive_angle = $negative_angle->absolute();    // +180°

Casting

To float sexadecimal degrees

You can cast the angle to float type, with optional precision up to PHP_FLOAT_DIG decimal places:

$alfa->toFloat();   // 180.211971543295645
$alfa->toFloat(4);  // 180.2119
$alfa->toFloat(200) // 180.211971543295645

You can specify a precision up to PHP_FLOAT_DIG decimal places. If the number of decimal places is not set, PHP_FLOAT_DIG is used.

To SexadecimalDegrees type

If you need an arbitrary precision, you can obtain a SexadecimalDegrees instance representing the sexadecimal value of the angle.

$sexadecimal = $alfa->toSexadecimalDegrees();
/** @var Number */
(string) $sexadecimal->value;// 180.2119715432956455962174521226543543
/** @var float */
$sexadecimal->value();       // 180.211971543295645
/** @var float */
$sexadecimal->value(3);      // 180.212
/** @var float */
$sexadecimal->value(12);     // 180.211971543296

The $value property is a Number object extending the BCMath\Number class, whose API is documented in marcoconsiglio/bcmath-extended.

The value() method cast the SexadecimalDegrees object to float. You can specify a precision up to PHP_FLOAT_DIG decimal places. If the number of decimal places is not set, PHP_FLOAT_DIG is used.

To float radian

You can cast the angle to radian (float), with optional precision up to PHP_FLOAT_DIG decimal places:

$alfa->toRadian();    // 3.141592653589793
$alfa->toRadian(3);   // 3.141
$alfa->toRadian(200); // 3.141592653589793 

You can specify a precision up to PHP_FLOAT_DIG decimal places. If the number of decimal places is not set, PHP_FLOAT_DIG is used.

To string sexagesimal

You can cast the angle to a string representation:

(string) $alfa; // 180° 30' 25.757385"

WARNING! In this case, maximum precision is unknown. The Seconds class uses the BCMath extension behind the scenes. The seconds value is stored with arbitrary precision, so in some cases the number of seconds could potentially have many digits, making the string very long.

Comparison

You can compare an Angle or AngularDistance object against a sexadecimal or sexagesimal value.

Comparisons are performed with absolute values (congruent comparison) when comparing Angles, meaning that $-90^\circ\cong+90^\circ$, while are performed with relative values when comparing AngularDistances, meaning that $-90^\circ\ncong+90^\circ$

If you need a relative comparison for Angles, you should cast the angle to a sexadecimal float and then perform the arithmetic comparison, meaning that $-90.0^\circ\lt+90.0^\circ$, but you will lose the benefit of arbitrary precision math provided by BcMath extension.

Each comparison can be performed against

  • a string angle (sexagesimal),
  • an int (sexagesimal degrees),
  • a float (sexadecimal degrees),
  • or another instance implementing the Angle interface.

Comparisons via radian values ​​are not available.

You can specify an optional precision expressed as the number of decimal places used to round the angle value. The precision is only used when comparing against a float (sexadecimal).

$alfa = Angle::createFromDecimal(89.999);
$alfa->isEqualTo(90.0, 0);  // true with precision 0
$alfa->isEqualTo(90.0, 3);  // false with precision 3

$\alpha > \beta$ (greater than)

$alfa = Angle::createFromDecimal(180);
$beta = Angle::createFromDecimal(90);
$gamma = Angle::createFromDecimal(360);
$alfa->isGreaterThan(90);       // true     180 >  90
$alfa->gt("90° 0' 0\"");        // true     180 >  90
$alfa->isGreaterThan($gamma);   // false    180 > 360
$alfa->gt($gamma);              // false    180 > 360

$\alpha ≧ \beta$ (greater than or equal)

$alfa = Angle::createFromDecimal(180);
$beta = Angle::createFromDecimal(90);
$gamma = Angle::createFromDecimal(90);
$alfa->isGreaterThanOrEqualTo(90);        // true 180 ≧  90
$alfa->gte("180 0' 0\"");               // true 180 ≧ 180
$beta->isGreaterThanOrEqualTo($alfa);    // true  90 ≧ 180
$beta->gte(90);                         // true  90 ≧  90

$\alpha < \beta$ (less than)

$alfa = Angle::createFromDecimal(90);
$beta = Angle::createFromDecimal(180);
$alfa->isLessThan(180);     // true  90 < 180
$alfa->lt(180);             // true  90 < 180
$alfa->isLessThan($beta);   // true  90 < 180
$beta->lt($alfa);           // false 180 < 90

$\alpha ≦ \beta$ (less than or equal)

$alfa = Angle::createFromDecimal(90);
$beta = Angle::createFromDecimal(180);
$alfa->isLessThanOrEqualTo(180);    // true 90 ≦ 180
$alfa->lte(90);                     // true 90 ≦ 90
$alfa->isLessThanOrEqualTo($beta);  // false 90 ≦ 180
$alfa->lte($beta);                  // false 90 ≦ 180

$\alpha \cong \beta$ (equal)

$alfa = Angle::createFromDecimal(180);
$beta = Angle::createFromDecimal(180);
$gamma = Angle::createFromDecimal(-180);
$alfa->isEqualTo($beta);  // true 180 ≅ 180
$alfa->eq($gamma);        // true 180 ≅ -180

$\alpha \ncong \beta$ (different)

$alfa = Angle::createFromDecimal(90);
$beta = Angle::createFromDecimal(180);
$alfa->isDifferentThan(180);        // true   90 ≇ 180
$alfa->not(180);                    // true   90 ≇ 180
$alfa->isDifferentThan(-90);        // false  90 ≇ -90
$beta->not($alfa);                  // true   180 ≇ 90

Fuzzy Comparison

When comparing two Angles sometimes their difference is negligible. In this case you can use a fuzzy comparison specifing a delta error Angle within which the comparison will be succesful.

Delta (Δ) is the double of epsilon error (±ε).

$\alpha \approxeq \beta$ (almost equal)

$alfa = Angle::createFromDecimal(90.345);
$beta = Angle::createFromValue(90);
$delta = Angle::createFromValue(4); // ±2° error
$alfa->fuzzyEqual($beta, $delta); // true
$alfa->feq($beta, $delta); // true

Algebraic sum between two angles

You can sum two angles. An angle of type AngularDistance do not have the absSum() methods.

Relative sum

The relative sum can return both positive or negative angle.

$alfa = Angle::createFromDecimal(180);
$beta = Angle::createFromDecimal(-270);
$gamma = 
         $alfa    //  180° + 
   ->sum($beta);  // -270° =
(string) $gamma;  //  -90° 

Absolute sum

The absolute sum will always return a positive angle.

$alfa = Angle::createFromDecimal(180);
$beta = Angle::createFromDecimal(-270);
$gamma = 
           $alfa    // 180° +
  ->absSum($beta);  //-270° =
(string) $gamma;    // 270°
$alfa = Angle::createFromDecimal(-180);
$beta = Angle::createFromDecimal(-270);
$gamma = 
           $alfa    // -180° +
  ->absSum($beta);  // -270°
(string) $gamma;    //  270°

Relative distance

You can calculate the relative distance between two Angles.

$alfa = Angle::createFromValues(180);
$beta = Angle::createFromValues(90);
$distance = AngularDistance::between($alfa, $beta);

FakerPHP support

This library provides support to FakerPHP through the WithAngleFaker trait. Here's a list of the available methods.

Method Return type Min (included) Min (excluded) Max (included) Max (excluded)
randomPrecision() int 0 PHP_FLOAT_DIG
randomDegrees() Degrees 359°
randomMinutes() Minutes 0' 59'
randomSeconds() Seconds 0" 60"
randomAngle() Angle -360° +360°
positiveRandomAngle() Angle +360°
negativeRandomAngle() Angle -360°
randomDirection() Direction CLOCKWISE COUNTER_CLOCKWISE
randomSexagesimalString() string -360° +360°
randomSexagesimal() SexagesimalDegrees -360° +360°
positiveRandomSexagesimal() SexagesimalDegrees +360°
negativeRandomSexagesimal() SexagesimalDegrees -360°
randomSexadecimal() float -360° +360°
positiveRandomSexadecimal() float +360°
negativeRandomSexadecimal() float -360°
randomRadian() Radian -2π +2π
positiveRandomRadian() Radian 0 +2π
negativeRandomRadian() Radian -2π 0
positiveRandomAngularDistance() AngularDistance +180°
negativeRandomAngularDistance() AngularDistance -180°

Check the API documentation to find out more info about these methods.

API documentation

You can read the code documentation in ./docs/html/index.html.

marcoconsiglio/goniometry 适用场景与选型建议

marcoconsiglio/goniometry 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 482 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 10 月 08 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「seconds」 「Degrees」 「angle」 「Minutes」 「radian」 「angle object」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 marcoconsiglio/goniometry 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 marcoconsiglio/goniometry 我们能提供哪些服务?
定制开发 / 二次开发

基于 marcoconsiglio/goniometry 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 482
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 36
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-10-08