範例:http://www.zhaojz.com.cn/demo/draw9.html
//畫切線
//point 圓外的一點
//dot 圓心
//r 半徑
function drawCircleTangent(point, dot, r){
//畫輔助線-start
var color = 'DarkRed'; //切線的顏色
var color2 = "#ccc"; //其它輔助線的顏色
drawLine(dot, [dot[0] 9*r,dot[1]], {color: color2}); // 延長圓心所在的水平線
drawLine(dot, [dot[0],dot[1]-4*r], {color: color2}); // 畫出圓心所在的垂直線
drawPoint({
pw:2,ph:2,color:'DarkRed',point: [dot[0] 9*r,dot[1],'x']
});
drawPoint({
pw:2,ph:2,color:'DarkRed',point: [dot[0],dot[1]-4*r,'y']
});
drawLine(point, [point[0],dot[1]], {color: color2}); // 畫出point到x軸的垂直線
drawLine(point, dot, {color: color2}); // 連接point與dot
drawLine([point[0]-2*r, point[1]], [point[0] 2*r, point[1]], {color: color2}); //畫point所在的水平線
//畫輔助線-end
//point.push('point');
drawPoint({
pw:2,ph:2,color:'DarkRed',point: point
});
//dot.push('centre');
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;
sinD = 0;
var conD = 0;
開關(象限){
狀況1:
sinC = cosB*cosA sinB*sinA; //sinC = sin(90 (B-A)) = cos(B-A) = cosB*cosA sinB*sinA
有C = -(無B*cosA-cosB*無A); //cosC = cos(90 (B-A)) = -sin(B-A) = -(sinB*cosA-cosB*sinA)
sinD = -(cosA*cosB-sinA*sinB); //sinD = sin(270-(AB))
withD = -(無A*cosB cosA*無B); //conD = cos(270-(AB))
休息;
狀況2:
sinC = -(cosB*cosA-sinB*sinA); //sinC = sin(-90 (AB))
conC = sinA*cosB cosA*sinB; //conC = cos(-90 (AB))
sinD = cosA*cosB sinA*sinB; //sinD = sin(90 (A-B))
withD = -(無A*cosB-cosA*無B); //conD = cos(90 (A-B))
休息;
狀況3:
sinC = -(cosA*cosB sinA*sinB); //sinC = sin(-90 (A-B))
有C = -(無A*cosB-cosA*無B); //conC = cos(-90 (A-B))
sinD = (cosA*cosB-sinA*sinB);
conD = sinA*cosB cosA*sinB;
休息;
狀況4:
sinC = cosA*cosB-sinA*sinB;
有C = -(無A*cosB cosA*沒有B)
sinD = -(cosA*cosB sinA*sinB); //sinD = sin(270 (A-B))
有D = (無A*cosB-cosA*無B); //conD = cos(270 (A-B))
休息;
預設值:
}
var tangentPointA = [點[0] b*conC, 點[1] b*sinC]; //套裝A位置
drawLine(點, tangentPointA, {顏色: 顏色}); //畫出切線
drawLine(點, tangentPointA, {顏色: color2}); //我期待見到你
//drawArc(point, 17, (象限==1 ||象限==4?180:0)-(象限==2 ||象限==3?(-1):1)*Math.and(sinC )*180/Math.PI, 0);
var tangentPointB = [點[0] b*conD, 點[1] b*sinD]; //手提箱B
drawLine(點, tangentPointB, {顏色: 顏色}); //畫出切線
drawLine(點, tangentPointB, {顏色: color2}); //我期待見到你
//drawArc(point, 27, (象限==1 ||象限==4?180:0)-(象限==2 ||象限==3?(-1):1)*Math.and(sinD )*180/Math.PI, 0);
drawPoint({ //描點
pw:3,ph:3,顏色:'DarkRed',重點:tangentPointA
});
drawPoint({ //描點
pw:3,ph:3,顏色:'DarkRed',重點:tangentPointB
});
//畫輔助弧
//(象限==1 ||象限==4?360:0)
drawArc(point, b, 60, (象限==1 ||象限==4?180:0)-(象限==2 ||象限==3?(-1):1)*Math.and(sinC )*180/Math.PI-5);
}