Created
October 22, 2013 19:18
-
-
Save k0t0vich/7106513 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package ru.yandex.utils.math { | |
| public class AngleRange { | |
| private var _min:Number; | |
| private var _max:Number; | |
| /** | |
| * Диапазон углов. | |
| * <p> | |
| * Этот класс не учитывает систему отсчета углов. Это может быть геометрическая | |
| * система (углы отсчитываются от положительного направления оси Ox против часовой | |
| * стрелки), либо географическая (углы отсчитываются от направления на север по | |
| * часовой стрелке), либо любая другая. | |
| * </p> | |
| * | |
| * @param minRadians Начальный угол в радианах. | |
| * @param maxRadians Конечный угол в радианах. | |
| */ | |
| public function AngleRange(minRadians:Number, maxRadians:Number) { | |
| _min = AngleUtil.normRadians(minRadians); | |
| _max = AngleUtil.normRadians(maxRadians); | |
| } | |
| /** | |
| * Проверка попадания значения угла в диапазон. | |
| * | |
| * @param radians Значение проверяемого угла в радианах. | |
| * | |
| * @return Если значение попадает в диапазон - <code>true</code>, в противном случае - | |
| * <code>false</code>. | |
| */ | |
| public function containsValue(radians:Number):Boolean { | |
| var normalized:Number = AngleUtil.normRadians(radians); | |
| if (_min <= _max) { | |
| return (_min <= normalized) && (normalized <= _max); | |
| } | |
| return (normalized <= _max) || (_min <= normalized); | |
| } | |
| /** | |
| * @return Разница между начальным и конечным углом дианазона. Значение выдается в | |
| * радианах, в дианазоне [0; 360). | |
| */ | |
| public function get size():Number { | |
| var result:Number = AngleUtil.normRadians(_max - _min); | |
| return (result >= 0) ? result : (result + AngleUtil.TWO_PI); | |
| } | |
| public function get bisector():Number { | |
| return AngleUtil.normRadians(_min + size / 2); | |
| } | |
| public function get min():Number { | |
| return _min; | |
| } | |
| public function get max():Number { | |
| return _max; | |
| } | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package ru.yandex.utils.math { | |
| public class AngleUtil { | |
| public static const HALF_PI:Number = 0.5 * Math.PI; | |
| public static const TWO_PI:Number = Math.PI + Math.PI; | |
| public static const RAD_TO_DEG:Number = 180 / Math.PI; | |
| public static const DEG_TO_RAD:Number = Math.PI / 180; | |
| private static const RANGE_RAD:Number = 0x7FFFFFFF / Math.PI; | |
| private static const RANGE_DEG:Number = 0x7FFFFFFF / 180; | |
| /** | |
| * Нормализация угла. | |
| * | |
| * @param angle Исходный угол в радианах. | |
| * | |
| * @return Значение в диапазоне [-PI, PI). | |
| * | |
| */ | |
| public static function normRadians(angle:Number):Number { | |
| return int(angle * RANGE_RAD) / RANGE_RAD; | |
| } | |
| public static function normRadiansTo2PI(angle:Number):Number { | |
| var tmp:Number = normRadians(angle); | |
| return tmp > 0 ? tmp : TWO_PI + tmp; | |
| } | |
| public static function degreesToRadians(angle:Number):Number { | |
| return DEG_TO_RAD * angle; | |
| } | |
| public static function radiansToDegrees(angle:Number):Number { | |
| return RAD_TO_DEG * angle; | |
| } | |
| /** | |
| * Нормализация угла. | |
| * | |
| * @param angle Исходный угол в градусах. | |
| * | |
| * @return Значение в диапазоне [-180, 180). | |
| */ | |
| public static function normDegrees(angle:Number):Number { | |
| return int(angle * RANGE_DEG) / RANGE_DEG; | |
| } | |
| /** | |
| * Разница между двумя углами. | |
| * <p>Определяет величину угла между двумя заданными углами</p> | |
| * @param radians1 | |
| * @param radians2 | |
| * @return | |
| * | |
| */ | |
| public static function diff(radians1:Number, radians2:Number):Number { | |
| var diff:Number = (radians2 % TWO_PI) - (radians1 % TWO_PI); | |
| return normRadians(diff); | |
| } | |
| public static function average(radians1:Number, ... radians):Number { | |
| if (radians.length == 0) { | |
| return normRadians(radians1); | |
| } | |
| var angles:Array = [normRadians(radians1)]; | |
| for (var i:int = 0; i < radians.length; i++) { | |
| angles.push(normRadians(radians[i])); | |
| } | |
| var d:Number = diff(angles[0], angles[1]); | |
| var maxDiff:Number = Math.abs(d); | |
| var maxRange:AngleRange = (d >= 0) ? new AngleRange(angles[0], angles[1]) | |
| : new AngleRange(angles[1], angles[0]); | |
| for (var j:int = 1; j < angles.length - 1; j++) { | |
| d = diff(angles[j], angles[j + 1]); | |
| if (Math.abs(d) > maxDiff) { | |
| maxDiff = Math.abs(d); | |
| maxRange = (d >= 0) ? new AngleRange(angles[j], angles[j + 1]) | |
| : new AngleRange(angles[j + 1], angles[j]); | |
| } | |
| } | |
| var zeroAngle:Number = maxRange.bisector; | |
| var sum:Number = 0; | |
| for each (var angle:Number in angles) { | |
| sum += normRadians(angle - zeroAngle); | |
| } | |
| return normRadians(sum / angles.length + zeroAngle); | |
| } | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package ru.yandex.utils.math { | |
| import flash.geom.Point; | |
| /** | |
| * Возвращает точку p3 перпендикуляра,такую, что | |
| * угол (p1p2, p2p3) = 90 и длина вектора p2p3 = length | |
| * Используется подобие прямоугольных прямоугольников | |
| * @param p1 | |
| * @param p2 | |
| * @param length | |
| * @return | |
| */ | |
| public function getOrthogonalPoint(p1:Point, p2:Point, length:Number = 1):Point { | |
| var dP:Point = p2.subtract(p1); | |
| // коэффициент подобия | |
| var k:Number = length / dP.length; | |
| var dx:Number = k * dP.y; | |
| var dy:Number = -k * dP.x; | |
| var result:Point = new Point(dx, dy); | |
| result = result.add(p2); | |
| return result; | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package ru.yandex.utils.math { | |
| import flash.geom.Point; | |
| public class IntersectUtil { | |
| public static function getLinesIntersectionPoint(a1:Point, a2:Point, b1:Point, b2:Point):Point { | |
| var d:Number = (a1.x - a2.x) * (b2.y - b1.y) - (a1.y - a2.y) * (b2.x - b1.x); | |
| var da:Number = (a1.x - b1.x) * (b2.y - b1.y) - (a1.y - b1.y) * (b2.x - b1.x); | |
| var db:Number = (a1.x - a2.x) * (a1.y - b1.y) - (a1.y - a2.y) * (a1.x - b1.x); | |
| if (Math.abs(d) < 0.000001) { | |
| return null; | |
| } else { | |
| var ta:Number = da / d; | |
| var tb:Number = db / d; | |
| if ((0 <= ta) && (ta <= 1) && (0 <= tb) && (tb <= 1)) { | |
| var x:Number = a1.x + ta * (a2.x - a1.x); | |
| var y:Number = a1.y + ta * (a2.y - a1.y); | |
| return new Point(x, y); | |
| } | |
| } | |
| return null; | |
| } | |
| public static function getPoligonsIntersectionPoints(polygone1:Array, | |
| poligone2:Array):Array { | |
| var len1:uint = polygone1.length; | |
| var len2:uint = poligone2.length; | |
| var result:Array = []; | |
| for (var i:int = 0; i < len1; i++) { | |
| var p1:Point = Point(polygone1[i]); | |
| var p2:Point = Point(polygone1[(i + 1) % len1]); | |
| for (var j:int = 0; j < len2; j++) { | |
| var p3:Point = Point(poligone2[j]); | |
| var p4:Point = Point(poligone2[(j + 1) % len2]); | |
| var intersection:Point = getLinesIntersectionPoint(p1, p2, p3, p4); | |
| if (intersection) { | |
| result.push(intersection); | |
| } | |
| } | |
| } | |
| return result.length > 0 ? result : null; | |
| } | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package ru.yandex.utils.math { | |
| public class NumberUtil { | |
| public static function interpolate(amount:Number, begin:Number, end:Number):Number { | |
| return begin + (end - begin) * amount; | |
| } | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package ru.yandex.utils.math { | |
| public class Range { | |
| private var _min:Number; | |
| private var _max:Number; | |
| public static function fromMinAndLength(min:Number, length:Number):Range { | |
| return new Range(min, min + length); | |
| } | |
| public static function fromMiddleAndDiff(middle:Number, diff:Number):Range { | |
| return new Range(middle - Math.abs(diff), middle + Math.abs(diff)); | |
| } | |
| public function Range(min:Number = NaN, max:Number = NaN) { | |
| if (!isNaN(min)) { | |
| _min = min; | |
| } | |
| if (!isNaN(max)) { | |
| _max = max; | |
| } | |
| validate(); | |
| } | |
| public function interpolate(pos:Number):Number { | |
| return _min + (_max - _min) * pos; | |
| } | |
| public function intersects(r:Range):Boolean { | |
| return defined && r.defined && (_min <= r._max) && (_max >= r._min); | |
| } | |
| public function restrict(value:Number):Number { | |
| if (value < _min) { | |
| return _min; | |
| } | |
| if (value > _max) { | |
| return _max; | |
| } | |
| return value; | |
| } | |
| /** | |
| * Рассчитывает значения точек, полученных разбиением диапазона на | |
| * <code>numParts</code> равных отрезков. | |
| * | |
| * <p>В результирующем массиве будет <code>numParts + 1</code> значений.</p> | |
| * | |
| * @param numParts Число отрезков, на которые нужно разбить диапазон. | |
| * | |
| * @return Набор значений. | |
| */ | |
| public function split(numParts:int):Array { | |
| var result:Array = [_min]; | |
| var delta:Number = (_max - _min) / numParts; | |
| var value:Number = _min; | |
| for (var i:int = 1; i < numParts; i++) { | |
| value += delta; | |
| result.push(value); | |
| } | |
| result.push(_max); | |
| return result; | |
| } | |
| public function equals(other:Range):Boolean { | |
| return other && (_min == other._min) && (_max == other._max); | |
| } | |
| public function clone():Range { | |
| return new Range(_min, _max); | |
| } | |
| public function toString():String { | |
| return "{" + _min + ", " + _max + "}"; | |
| } | |
| private function validate():void { | |
| if (!isNaN(_min) && !isNaN(_max) && (_min > _max)) { | |
| throw new RangeError("Invalid range: min = " + _min + ", max = " + _max); | |
| } | |
| } | |
| public function get min():Number { | |
| return _min; | |
| } | |
| public function set min(value:Number):void { | |
| _min = value; | |
| validate(); | |
| } | |
| public function get max():Number { | |
| return _max; | |
| } | |
| public function set max(value:Number):void { | |
| _max = value; | |
| if (_max < _min) { | |
| _max = _min; | |
| } | |
| validate(); | |
| } | |
| public function get size():Number { | |
| return _max - _min; | |
| } | |
| private function get defined():Boolean { | |
| return !(isNaN(_min) || isNaN(_max)); | |
| } | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment