Angle提供一些列函数或成员来操作与空间角度相关的操作
源码
@requires jsts/algorithm/CGAlgorithms.js
#构造函数
jsts.algorithm.Angle = function() {};
成员-- 2π
jsts.algorithm.Angle.PI_TIMES_2 = 2.0 * Math.PI;
成员-- π/2
jsts.algorithm.Angle.PI_OVER_2 = Math.PI / 2.0;
成员--π/4
jsts.algorithm.Angle.PI_OVER_4 = Math.PI / 4.0;
顺时针
jsts.algorithm.Angle.COUNTERCLOCKWISE = jsts.algorithm.CGAlgorithms.COUNTERCLOCKWISE;
逆时针
jsts.algorithm.Angle.CLOCKWISE = jsts.algorithm.CGAlgorithms.CLOCKWISE;
无方向性角度
jsts.algorithm.Angle.NONE = jsts.algorithm.CGAlgorithms.COLLINEAR;
弧度转度
jsts.algorithm.Angle.toDegrees = function(radians) {
return (radians * 180) / Math.PI;
};
度转弧度
jsts.algorithm.Angle.toRadians = function(angleDegrees) {
return (angleDegrees * Math.PI) / 180.0;
};
计算角度
返回给定点的角度,如果只有一个坐标,则返回该点和原点连线的角度,如果参数有两个或多个,返回坐标直接的角度
jsts.algorithm.Angle.angle = function() {
if (arguments.length === 1) {
return jsts.algorithm.Angle.angleFromOrigo(arguments[0]);
}else {
return jsts.algorithm.Angle.angleBetweenCoords(arguments[0], arguments[1]);
}
};
返回p0到p1向量的角度信息
/**
* Returns the angle of the vector from p0 to p1,
* relative to the positive X-axis.
* The angle is normalized to be in the range [ -Pi, Pi ].
*
* @param {jsts.geom.Coordinate} p0 a coordinate.
* @param {jsts.geom.Coordinate} p1 a coordinate.
* @return {Number}
* the normalized angle (in radians) that p0-p1 makes with the positive x-axis.
*/
jsts.algorithm.Angle.angleBetweenCoords = function(p0, p1) {
var dx, dy;
dx = p1.x - p0.x;
dy = p1.y - p0.y;
return Math.atan2(dy, dx);
};
返回坐标原点到P点的向量角度
/**
* Returns the angle that the vector from (0,0) to p,
* relative to the positive X-axis.
* The angle is normalized to be in the range ( -Pi, Pi ].
*
* @param {jsts.geom.Coordinate} p a coordinate.
* @return {Number} the normalized angle (in radians) that p makes with the positive x-axis.
*/
jsts.algorithm.Angle.angleFromOrigo = function(p) {
return Math.atan2(p.y, p.x);
};
返回p0 ->p1->p2构成的角度是否为锐角
/**
* Tests whether the angle between p0-p1-p2 is acute.
* An angle is acute if it is less than 90 degrees.
*
* Note: this implementation is not precise (determistic) for angles very close to 90 degrees.
*
* @param {jsts.geom.Coordinate} p0 an endpoint of the angle.
* @param {jsts.geom.Coordinate} p1 the base of the angle.
* @param {jsts.geom.Coordinate} p2 the other endpoint of the angle.
* @return {Boolean}
* true if the angle is acute.
*/
jsts.algorithm.Angle.isAcute = function(p0, p1, p2) {
var dx0, dy0, dx1, dy1, dotprod;
//relies on fact that A dot B is positive if A ang B is acute
dx0 = p0.x - p1.x;
dy0 = p0.y - p1.y;
dx1 = p2.x - p1.x;
dy1 = p2.y - p1.y;
dotprod = dx0 * dx1 + dy0 * dy1;
return dotprod > 0;
};
返回p0->p1->p2直接的角度是否为钝角
/**
* Tests whether the angle between p0-p1-p2 is obtuse.
* An angle is obtuse if it is greater than 90 degrees.
*
* 当角度非常接近90度的时候结果可能不是真精确
*
* @param {jsts.geom.Coordinate} p0 an endpoint of the angle.
* @param {jsts.geom.Coordinate} p1 the base of the angle.
* @param {jsts.geom.Coordinate} p2 the other endpoint of the angle.
* @return {Boolean} true if the angle is obtuse.
*/
jsts.algorithm.Angle.isObtuse = function(p0, p1, p2) {
var dx0, dy0, dx1, dy1, dotprod;
//relies on fact that A dot B is negative iff A ang B is obtuse
dx0 = p0.x - p1.x;
dy0 = p0.y - p1.y;
dx1 = p2.x - p1.x;
dy1 = p2.y - p1.y;
dotprod = dx0 * dx1 + dy0 * dy1;
return dotprod < 0;
};
返回两个向量之间的最近小角度,无方向性的,值再[0,Pi)之间
/**
* Returns the unoriented smallest angle between two vectors.
* The computed angle will be in the range [0, Pi).
* @param {jsts.geom.Coordinate} tip1 the tip of one vector.
* @param {jsts.geom.Coordinate} tail the tail of each vector.
* @param {jsts.geom.Coordinate} tip2 the tip of the other vector.
* @return {Number} the angle between tail-tip1 and tail-tip2.
*/
jsts.algorithm.Angle.angleBetween = function(tip1, tail, tip2) {
var a1, a2;
a1 = jsts.algorithm.Angle.angle(tail, tip1);
a2 = jsts.algorithm.Angle.angle(tail, tip2);
return jsts.algorithm.Angle.diff(a1, a2);
};
返回两个向量之间的角度(有方向性 V1->V2),值应该在(-Pi,Pi]之间
/**
* Returns the oriented smallest angle between two vectors.
* The computed angle will be in the range (-Pi, Pi].
* A positive result corresponds to a counterclockwise rotation
* from v1 to v2;
* a negative result corresponds to a clockwise rotation.
*
* @param {jsts.geom.Coordinate} tip1 the tip of v1.
* @param {jsts.geom.Coordinate} tail the tail of each vector.
* @param {jsts.geom.Coordinate} tip2 the tip of v2.
* @return {Number} the angle between v1 and v2, relative to v1.
*/
jsts.algorithm.Angle.angleBetweenOriented = function(tip1, tail, tip2) {
var a1, a2, angDel;
a1 = jsts.algorithm.Angle.angle(tail, tip1);
a2 = jsts.algorithm.Angle.angle(tail, tip2);
angDel = a2 - a1;
// normalize, maintaining orientation
if (angDel <= -Math.PI) {
return angDel + jsts.algorithm.Angle.PI_TIMES_2;
}
if (angDel > Math.PI) {
return angDel - jsts.algorithm.Angle.PI_TIMES_2;
}
return angDel;
};
计算环Ring内部两条线段的角度 值再[0,2Pi]之间
/**
* Computes the interior angle between two segments of a ring. The ring is
* assumed to be oriented in a clockwise direction. The computed angle will be
* in the range [0, 2Pi]
*
* @param {jsts.geom.Coordinate} p0 a point of the ring.
* @param {jsts.geom.Coordinate} p1 the next point of the ring.
* @param {jsts.geom.Coordinate} p2 the next point of the ring.
* @return {Number} the interior angle based at p1.
*/
jsts.algorithm.Angle.interiorAngle = function(p0, p1, p2) {
var anglePrev, angleNext;
anglePrev = jsts.algorithm.Angle.angle(p1, p0);
angleNext = jsts.algorithm.Angle.angle(p1, p2);
return Math.abs(angleNext - anglePrev);
};
判断两个角度直接是否为顺时针还是逆时针
/**
* Returns whether an angle must turn clockwise or counterclockwise to overlap another angle.
* @param {Number} ang1 an angle (in radians).
* @param {Number} ang2 an angle (in radians).
* @return {Number} whether a1 must turn CLOCKWISE, COUNTERCLOCKWISE or NONE to overlap a2.
*/
jsts.algorithm.Angle.getTurn = function(ang1, ang2) {
var crossproduct = Math.sin(ang2 - ang1);
if (crossproduct > 0) {
return jsts.algorithm.Angle.COUNTERCLOCKWISE;
}
if (crossproduct < 0) {
return jsts.algorithm.Angle.CLOCKWISE;
}
return jsts.algorithm.Angle.NONE;
};
/**
* Computes the normalized value of an angle, which is the
* equivalent angle in the range ( -Pi, Pi ].
* @param {Number} angle the angle to normalize.
* @return {Number} an equivalent angle in the range (-Pi, Pi].
*/
jsts.algorithm.Angle.normalize = function(angle) {
while (angle > Math.PI) {
angle -= jsts.algorithm.Angle.PI_TIMES_2;
}
while (angle <= -Math.PI) {
angle += jsts.algorithm.Angle.PI_TIMES_2;
}
return angle;
};
规则化一个正角度值,使值在[0, 2Pi]之间
/**
* Computes the normalized positive value of an angle, which is the
* equivalent angle in the range [ 0, 2*Pi ).
* E.g.:
*
* - normalizePositive(0.0) = 0.0
*
- normalizePositive(-PI) = PI
*
- normalizePositive(-2PI) = 0.0
*
- normalizePositive(-3PI) = PI
*
- normalizePositive(-4PI) = 0
*
- normalizePositive(PI) = PI
*
- normalizePositive(2PI) = 0.0
*
- normalizePositive(3PI) = PI
*
- normalizePositive(4PI) = 0.0
*
*
* @param {Number}
* angle the angle to normalize, in radians.
* @return {Number}
* an equivalent positive angle.
*/
jsts.algorithm.Angle.normalizePositive = function(angle) {
if (angle < 0.0) {
while (angle < 0.0) {
angle += jsts.algorithm.Angle.PI_TIMES_2;
}
// in case round-off error bumps the value over
if (angle >= jsts.algorithm.Angle.PI_TIMES_2) {
angle = 0.0;
}
}
else {
while (angle >= jsts.algorithm.Angle.PI_TIMES_2) {
angle -= jsts.algorithm.Angle.PI_TIMES_2;
}
// in case round-off error bumps the value under
if (angle < 0.0) {
angle = 0.0;
}
}
return angle;
};
计算两个无向角度之间的最小差值
/**
* Computes the unoriented smallest difference between two angles.
* The angles are assumed to be normalized to the range [-Pi, Pi].
* The result will be in the range [0, Pi].
*
* @param {Number} ang1 the angle of one vector (in [-Pi, Pi] ).
* @param {Number} ang2 the angle of the other vector (in range [-Pi, Pi] ).
* @return {Number} the angle (in radians) between the two vectors (in range [0, Pi] ).
*/
jsts.algorithm.Angle.diff = function(ang1, ang2) {
var delAngle;
if (ang1 < ang2) {
delAngle = ang2 - ang1;
} else {
delAngle = ang1 - ang2;
}
if (delAngle > Math.PI) {
delAngle = (2 * Math.PI) - delAngle;
}
return delAngle;
};