Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNSUNI-94: Fix: Changed trigonometric output to double #16

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading