js 获取圆外一点与圆的切点坐标函数(摘自网络,可以使用)

// 原帖地址:http://www.cnblogs.com/zhaojz/p/4218026.html
//获取切点坐标 point 圆外的一点 dot 圆心 r 半径
function getCircleTangent(point, dot, r) {
var r_square = Math.pow(r, 2); // r的平方
var point_v = point[1] - dot[1]; //point到x轴的距离的平方
var point_h = point[0] - dot[0]; //point到y轴的距离的平方
var c_square = Math.pow(point_v, 2) + Math.pow(point_h, 2); //point到圆心的距离的平方

var c = Math.sqrt(c_square); //point到圆心的距离

var sinA = Math.abs(point_v) / c; //sinA
var cosA = Math.abs(point_h) / c; //cosA
var b_square = c_square - r_square; //point到切点的距离的平方
var b = Math.sqrt(b_square); //point到切点的距离

var sinB = b / c; //sinB
var cosB = r / c; //cosB
//以圆心为坐标圆点,确定point所在的象限
var quadrant = 1; //默认值
var pm_h = point_h == 0 ? point_h : point_h / Math.abs(point_h); //水平方向
var pm_v = point_v == 0 ? point_v : point_v / Math.abs(point_v); //垂直方向
var hv = pm_h * pm_v; //相乘,-1时point在一三象限,+1时point在二四象限,0时point在轴上
switch (hv) {
case 1:
if ((pm_h + pm_v) == -2) {
quadrant = 2; //第二象限
} else {
quadrant = 4; //第四象限
}
break;
case -1:
if ((pm_h - pm_v) == -2) {
quadrant = 3; //第三象限
}
break;
case 0:
if ((pm_h + pm_v) == -1) { //point在x轴的负半轴或者y轴的正半轴时,断定point在第二象限
quadrant = 2;
}
if ((pm_h + pm_v) == 1) { //point在x轴的正半轴或者y轴的负半轴时,断定point在第四象限
quadrant = 4;
}
break;
default:
}
var sinC = 0;
var conC = 0;
var sinD = 0;
var conD = 0;
switch (quadrant) {
case 1:
sinC = cosB * cosA + sinB * sinA; //sinC = sin(90+(B-A)) = cos(B-A) = cosB*cosA+sinB*sinA
conC = -(sinB * cosA - cosB * sinA); //cosC = cos(90+(B-A)) = -sin(B-A) = -(sinB*cosA-cosB*sinA)
sinD = -(cosA * cosB - sinA * sinB); //sinD = sin(270-(A+B))
conD = -(sinA * cosB + cosA * sinB); //conD = cos(270-(A+B))
break;
case 2:
sinC = -(cosB * cosA - sinB * sinA); //sinC = sin(-90+(A+B))
conC = sinA * cosB + cosA * sinB; //conC = cos(-90+(A+B))
sinD = cosA * cosB + sinA * sinB; //sinD = sin(90+(A-B))
conD = -(sinA * cosB - cosA * sinB); //conD = cos(90+(A-B))
break;
case 3:
sinC = -(cosA * cosB + sinA * sinB); //sinC = sin(-90+(A-B))
conC = -(sinA * cosB - cosA * sinB); //conC = cos(-90+(A-B))
sinD = (cosA * cosB - sinA * sinB);
conD = sinA * cosB + cosA * sinB;
break;
case 4:
sinC = cosA * cosB - sinA * sinB;
conC = -(sinA * cosB + cosA * sinB)
sinD = -(cosA * cosB + sinA * sinB); //sinD = sin(270+(A-B))
conD = (sinA * cosB - cosA * sinB); //conD = cos(270+(A-B))
break;
default:
}
return {
point1: {x: point[0] + b * conC, y: point[1] + b * sinC},
point2: {x: point[0] + b * conD, y: point[1] + b * sinD}
}; //两个切点位置
}
posted @ 2017-05-12 15:16  Yishin  阅读(1551)  评论(0)    收藏  举报