Skip to content

Commit

Permalink
SNSUNI-94: Fix: Changed trigonometric output to double
Browse files Browse the repository at this point in the history
  • Loading branch information
pjazdzyk committed May 26, 2024
1 parent 824f16f commit 9ce284f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 87 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,18 +353,18 @@ Distance reducedDistance2 = roadLength.log10(); // 2.0

```java
Angle exampleAngle = Angle.ofDegrees(90);
Angle sinResult = exampleAngle.sin(); // 1
Angle cosResult = exampleAngle.cos(); // 0
double sinResult = exampleAngle.sin(); // 1
double cosResult = exampleAngle.cos(); // 0

Angle angle45 = exampleAngle.withValue(45);
Angle tanResult = angle45.tan(); // 1
Angle cotResult = angle45.cot(); // 1
double tanResult = angle45.tan(); // 1
double cotResult = angle45.cot(); // 1

Angle angleRad1 = exampleAngle.toRadians().withValue(1);
Angle aSinResult = angleRad1.asin(); // 1.570796(..)
Angle aCosResult = angleRad1.acos(); // 0
Angle aTanResult = angleRad1.atan(); // 0.785398(..)
Angle aCotResult = angleRad1.acot(); // 0.785398(..)
double aSinResult = angleRad1.asin(); // 1.570796(..)
double aCosResult = angleRad1.acos(); // 0
double aTanResult = angleRad1.atan(); // 0.785398(..)
double aCotResult = angleRad1.acot(); // 0.785398(..)
```
Please keep in mind that not all values belong to the domain of a given trigonometric function.
Some might throw an exception if they hold invalid value for a specific function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,39 @@
import java.util.function.DoubleUnaryOperator;

/**
* Interface representing a calculable quantity with operations for basic arithmetics.
* Interface representing a calculable quantity with operations for basic arithmetic and trigonometric functions.
*
* @param <Q> The type of {@link PhysicalQuantity} implementing this interface.
*/
public interface TrigonometricQuantity<Q extends CalculableQuantity<AngleUnit, Q>> extends CalculableQuantity<AngleUnit, Q> {

// Trigonometric
/**
* Calculate the sine of the physical quantity's value in a current unit.<p>
* If the quantity is an instance of {@link AngleUnit} its value will be automatically
* converted to radians before calculating resulting value.
* Calculates the sine of the physical quantity's value in its current unit.
* If the quantity is an instance of {@link AngleUnit}, its value will be automatically
* converted to radians before calculating the resulting value.
*
* @return A new physical quantity with the sine of the current value in a current unit.
* @return The sine of the current value.
*/
default Q sin() {
default double sin() {
return applyTrigonometricFunction(Math::sin);
}

/**
* Calculate the hyperbolic sine of the physical quantity's value.
* Calculates the hyperbolic sine of the physical quantity's value.
*
* @return A new physical quantity with the hyperbolic sine of the current value.
* @return The hyperbolic sine of the current value.
*/
default Q sinh() {
default double sinh() {
return applyTrigonometricFunction(Math::sinh);
}

/**
* Calculate the arcsine of the physical quantity's value.
* Calculates the arcsine of the physical quantity's value.
*
* @return A new physical quantity with the arcsine of the current value.
* @return The arcsine of the current value.
* @throws UnitSystemArgumentException if the value is out of the range [-1, 1].
*/
default Q asin() {
default double asin() {
double value = getValueInRadians();
if (value < -1 || value > 1) {
throw new UnitSystemArgumentException("Value out of range for arcsine. Valid range is [-1, 1].");
Expand All @@ -49,33 +48,30 @@ default Q asin() {
}

/**
* Calculate the cosine of the physical quantity's value in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the cosine of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the cosine of the current value.
* @return The cosine of the current value.
*/
default Q cos() {
default double cos() {
return applyTrigonometricFunction(Math::cos);
}

/**
* Calculate the hyperbolic cosine of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the hyperbolic cosine of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the hyperbolic cosine of the current value.
* @return The hyperbolic cosine of the current value.
*/
default Q cosh() {
default double cosh() {
return applyTrigonometricFunction(Math::cosh);
}

/**
* Calculate the arccosine of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the arccosine of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the arccosine of the current value.
* @return The arccosine of the current value.
* @throws UnitSystemArgumentException if the value is out of the range [-1, 1].
*/
default Q acos() {
default double acos() {
double value = getValueInRadians();
if (value < -1 || value > 1) {
throw new UnitSystemArgumentException("Value out of range for arccosine. Valid range is [-1, 1].");
Expand All @@ -84,13 +80,12 @@ default Q acos() {
}

/**
* Calculate the tangent of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the tangent of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the tangent of the current value.
* @return The tangent of the current value.
* @throws UnitSystemArgumentException if the value is an odd multiple of π/2.
*/
default Q tan() {
default double tan() {
double value = getValueInRadians();
if (isMultipleOfPiOverTwo(value)) {
throw new UnitSystemArgumentException("Tangent is undefined for odd multiples of π/2.");
Expand All @@ -99,81 +94,98 @@ default Q tan() {
}

/**
* Calculate the hyperbolic tangent of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the hyperbolic tangent of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the hyperbolic tangent of the current value.
* @return The hyperbolic tangent of the current value.
*/
default Q tanh() {
default double tanh() {
return applyTrigonometricFunction(Math::tanh);
}

/**
* Calculate the arctangent of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the arctangent of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the arctangent of the current value.
* @return The arctangent of the current value.
*/
default Q atan() {
default double atan() {
return applyTrigonometricFunction(Math::atan);
}

/**
* Calculate the cotangent of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the cotangent of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the cotangent of the current value.
* @return The cotangent of the current value.
* @throws UnitSystemArgumentException if the value is a multiple of π.
*/
default Q cot() {
default double cot() {
double value = getValueInRadians();
if (isMultipleOfPi(value)) {
throw new UnitSystemArgumentException("Cotangent is undefined for multiples of π.");
}
return withValue(1 / tan().getValue());
return 1 / tan();
}

/**
* Calculate the hyperbolic cotangent of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the hyperbolic cotangent of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the hyperbolic cotangent of the current value.
* @return The hyperbolic cotangent of the current value.
* @throws UnitSystemArgumentException if the value is 0.
*/
default Q coth() {
default double coth() {
double value = getValueInRadians();
if (value == 0) {
throw new UnitSystemArgumentException("Hyperbolic cotangent is undefined for 0.");
}
return withValue(1 / tanh().getValue());
return 1 / tanh();
}

/**
* Calculate the arccotangent of the physical quantity's in a current unit.
* Use toUnit(Unit) if intended to convert value in other supported unit.
* Calculates the arccotangent of the physical quantity's value in its current unit.
*
* @return A new physical quantity with the arccotangent of the current value.
* @return The arccotangent of the current value.
*/
default Q acot() {
return withValue(1 / atan().getValue());
default double acot() {
return 1 / atan();
}

@SuppressWarnings("unchecked")
private Q applyTrigonometricFunction(DoubleUnaryOperator unaryOperator) {
PhysicalQuantity<AngleUnit> unitInRadians = toUnit(AngleUnits.RADIANS);
double resultingValue = unaryOperator.applyAsDouble(unitInRadians.getValue());
return (Q) unitInRadians.withValue(resultingValue).toUnit(getUnitType());
/**
* Applies a trigonometric function to the physical quantity's value.
*
* @param unaryOperator the trigonometric function to apply.
* @return The result of the trigonometric function.
*/
private double applyTrigonometricFunction(DoubleUnaryOperator unaryOperator) {
double unitInRadians = getValueInRadians();
return unaryOperator.applyAsDouble(unitInRadians);
}

/**
* Gets the value of the physical quantity in radians.
*
* @return The value in radians.
*/
private double getValueInRadians() {
return toUnit(AngleUnits.RADIANS).getValue();
}

/**
* Checks if the value is a multiple of π/2.
*
* @param value the value to check.
* @return True if the value is a multiple of π/2, false otherwise.
*/
private boolean isMultipleOfPiOverTwo(double value) {
return Math.abs((value / (Math.PI / 2)) % 1) < 1e-10;
}

/**
* Checks if the value is a multiple of π.
*
* @param value the value to check.
* @return True if the value is a multiple of π, false otherwise.
*/
private boolean isMultipleOfPi(double value) {
return Math.abs((value / Math.PI) % 1) < 1e-10;
}

}
Loading

0 comments on commit 9ce284f

Please sign in to comment.