1<?php 2 3namespace LesserPHP\Utils; 4 5use Exception; 6use LesserPHP\Constants; 7 8/** 9 * Miscelaneous utility methods 10 */ 11class Util 12{ 13 /** 14 * Clamps a value between a minimum and maximum value. 15 * 16 * This function takes a value and two boundary values (maximum and minimum). 17 * It ensures that the provided value does not exceed the boundaries. 18 * If the value is less than the minimum, the minimum is returned. 19 * If the value is greater than the maximum, the maximum is returned. 20 * Otherwise, the original value is returned. 21 */ 22 public static function clamp(float $v, float $max = 1, float $min = 0): float 23 { 24 return min($max, max($min, $v)); 25 } 26 27 /** 28 * Quote a string for use in a regular expression 29 */ 30 public static function pregQuote(string $what): string 31 { 32 return preg_quote($what, '/'); 33 } 34 35 /** 36 * Return a boolean type 37 * 38 * @param mixed $a 39 */ 40 public static function toBool($a): array 41 { 42 if ($a) return Constants::TRUE; 43 return Constants::FALSE; 44 } 45 46 /** 47 * Converts numbers between different types of units 48 * 49 * @throws Exception 50 */ 51 public static function convert($number, $to): array 52 { 53 $value = Asserts::assertNumber($number); 54 $from = $number[2]; 55 56 // easy out 57 if ($from == $to) 58 return $number; 59 60 // check if the from value is a length 61 if (($from_index = array_search($from, Constants::LENGTH_UNITS)) !== false) { 62 // make sure to value is too 63 if (in_array($to, Constants::LENGTH_UNITS)) { 64 // do the actual conversion 65 $to_index = array_search($to, Constants::LENGTH_UNITS); 66 $px = $value * Constants::LENGTH_BASES[$from_index]; 67 $result = $px * (1 / Constants::LENGTH_BASES[$to_index]); 68 69 $result = round($result, 8); 70 return ['number', $result, $to]; 71 } 72 } 73 74 // do the same check for times 75 if (in_array($from, Constants::TIME_UNITS)) { 76 if (in_array($to, Constants::TIME_UNITS)) { 77 // currently only ms and s are valid 78 if ($to == 'ms') 79 $result = $value * 1000; 80 else $result = $value / 1000; 81 82 $result = round($result, 8); 83 return ['number', $result, $to]; 84 } 85 } 86 87 // lastly check for an angle 88 if (in_array($from, Constants::ANGLE_UNITS)) { 89 // convert whatever angle it is into degrees 90 switch ($from) { 91 case 'rad': 92 $deg = rad2deg($value); 93 break; 94 case 'turn': 95 $deg = $value * 360; 96 break; 97 case 'grad': 98 $deg = $value / (400 / 360); 99 break; 100 default: 101 $deg = $value; 102 break; 103 } 104 105 // Then convert it from degrees into desired unit 106 switch ($to) { 107 case 'rad': 108 $result = deg2rad($deg); 109 break; 110 case 'turn': 111 $result = $deg / 360; 112 break; 113 case 'grad': 114 $result = $deg * (400 / 360); 115 break; 116 default: 117 $result = $deg; 118 break; 119 } 120 121 $result = round($result, 8); 122 return ['number', $result, $to]; 123 } 124 125 // we don't know how to convert these 126 throw new Exception("Cannot convert $from to $to"); 127 } 128} 129