Skip to content

Instantly share code, notes, and snippets.

@aaronlademann-wf
Last active October 7, 2016 11:30
Show Gist options
  • Save aaronlademann-wf/ef9516cd80e29c516a91 to your computer and use it in GitHub Desktop.
Save aaronlademann-wf/ef9516cd80e29c516a91 to your computer and use it in GitHub Desktop.
Inverse Trigonometric Functions With Sass
// ----
// Sass (v3.3.7)
// Compass (v1.0.0.alpha.18)
// ----
/**
* Inverse Trigonometric Functions With Sass
*
* Functions that compute the values for angles whose
* sine, cosine, or tangent is known.
*
* http://thesassway.com/advanced/inverse-trigonometric-functions-with-sass
*/
$pi: pi();
$default-threshold: $pi/180/10;
//
// ANGLE CONVERSION HELPER
//
@function convert-angle($value, $unit-name) {
$factors: (
rad: 1rad,
deg: 180deg / $pi,
turn: .5turn / $pi,
grad: 200grad / $pi
);
@if not unitless($value) {
@warn '\n`#{$value}` should be unitless\n';
@return false;
}
@if not map-has-key($factors, $unit-name) {
@warn '\nUnit `#{$unit-name}` is not a valid unit. \nPlease make sure it is either `deg`, `rad`, `grad` or `turn`.\n';
@return false;
}
@return $value * map-get($factors, $unit-name);
}
//
// CALCULATE ARCSINE
// given an angle's sine (z),
// this fn will tell you the angle
//
@function asin($z, $unit-name: deg, $threshold: $default-threshold) {
$sum: 0;
$is-complement: false;
// make sure it works for negative $z values as well
$sign: $z / abs($z); // -1 or 1
$z: abs($z); // always positive
@if $z > sin($pi/4) {
$is-complement: true;
$z: sqrt(1 - pow($z, 2));
}
// add up terms to the sum and set the condition that we
// stop once we got to a term whose value is smaller
// than the threshold value which we pass to the function
$term: $z;
$i: 0; // current term's index
$k: 1; // previous term used in @while (below)
@if abs($z) <= 1 {
@while $term > $threshold {
$sum: $sum + $term;
$i: $i + 1; // iterate
$k: $k * (2 * $i - 1) / (2 * $i); // store previous term
$j: 2 * $i + 1;
$term: $k * pow($z, $j) / $j;
}
} @else {
@warn '\nabs(#{$z}) must be <= 1 in order for $term to get under the $threshold. \nInfinite Loop would result.\n';
@return false;
}
// multiply result by $sign again to ensure a
// negative number remains that way after computations
@return convert-angle($sign * (if($is-complement, $pi/2 - $sum, $sum)));
}
//
// CALCULATE ARCCOSINE
// In the case of an angle α in the [0,π] interval, cos(α)=sin(π/2−α).
// If we know cos(α)=z, then arcsin(z)=π/2−α,
// which gives us that α=π/2−arcsin(z)
//
@function acos($z, $unit-name: deg, $threshold: $default-threshold) {
@return convert-angle($pi/2 - asin($z, $threshold));
}
//
// CALCULATE ARCTANGENT
// tan(α)=sin(α)/cos(α). We also know that sin2(α)+cos2(α)=1,
// so we have that tan2(α)=sin2(α)/(1−sin2(α)).
// From this equality, we extract the sine depending on the tangent.
//
@function atan($z, $unit-name: deg, $threshold: $default-threshold) {
@return asin($z / sqrt(1 + pow($z, 2)), $threshold);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment