3

我得到 的是舞台上的两个圆圈,circ1 和 circ2。circ1 的半径为 60,circ2 的半径为 30。

circ2 可以在播放时在舞台周围拖动。

我想要 的是通过它们共同的外切线连接圆的两条线。这是为了把一张旧海报变成一个互动的乐趣盒。这是海报的链接,它可能会帮助您理解我的意思(尽管现在我只担心两个圈子自己)。

问题: 我知道如何用笔和纸找到共同的切线,但是当我试图设想如何用 Flash 可能理解的术语来表达这一点时,我的大脑就崩溃了。我不知道如何使用 ActionScript 来实现这一点。

我已经尝试过: 我环顾四周,这是我能找到的最接近我想要实现的目标(示例应用程序可在页面底部下载)。唯一的区别是这包括我不需要的内部切线。

不幸的是,这个源代码是用 Java 编写的,尽管我尽了最大的努力,但我对移植到 AS3 的理解还不够。

到目前为止,我自己设法实现的只是为每个圆的中心定义点,然后意识到我无法为变量制作快速求解方程。然后我花了几个小时谷歌搜索试图弄清楚如何从这里开始。

任何帮助将不胜感激,这是本周末到期的学校项目的工作。我可能已经咬得比我能在这里咀嚼的多,但现在回头已经太迟了。

提前致谢!

4

2 回答 2

4
function DrawTangents(p1 : Point, r1 : Number, p2 : Point, r2 : Number) : void {
    var dx = p2.x - p1.x;
    var dy = p2.y - p1.y;
    var dist = Math.sqrt(dx*dx + dy*dy);

    this.graphics.drawCircle(p1.x, p1.y, r1);
    this.graphics.drawCircle(p2.x, p2.y, r2);

    if (dist <= Math.abs(r2 - r1)) {
        // The circles are coinciding. There are no valid tangents.
        return;
    }

    // Rotation from the x-axis.
    var angle1 = Math.atan2(dy, dx);

    // Relative angle of the normals. This is equal for both circles.
    var angle2 = Math.acos((r1 - r2)/dist);

    this.graphics.moveTo(p1.x + r1 * Math.cos(angle1 + angle2),
                         p1.y + r1 * Math.sin(angle1 + angle2));
    this.graphics.lineTo(p2.x + r2 * Math.cos(angle1 + angle2),
                         p2.y + r2 * Math.sin(angle1 + angle2));

    this.graphics.moveTo(p1.x + r1 * Math.cos(angle1 - angle2),
                         p1.y + r1 * Math.sin(angle1 - angle2));
    this.graphics.lineTo(p2.x + r2 * Math.cos(angle1 - angle2),
                         p2.y + r2 * Math.sin(angle1 - angle2));
}
于 2012-08-20T12:34:53.840 回答
3

这是您为两个圆圈描述的工作代码 - 假设两个圆圈大小相同。否则它是一个近似值,因为它假设切点将在垂直于连接圆心的直线上。

var point1 : Point = new Point(100, 100);
var point2 : Point = new Point(300, 50);
var radius1 : int = 60;
var radius2 : int = 30;

// if you draw a line from the first circle origo to
// the second origo, this is the angle of that line
var ang : Number = Math.atan2(point2.y - point1.y, point2.x - point1.x);

// find the first point on the circumference that is orthogonal
// to the line intersecting the two circle origos
var start1 : Point = new Point(point1.x + Math.cos(ang + Math.PI / 2) * radius1, 
                               point1.y + Math.sin(ang + Math.PI/2)* radius1);
var end1 : Point = new Point(point2.x + Math.cos(ang + Math.PI / 2) * radius2, 
                             point2.y + Math.sin(ang + Math.PI/2)* radius2);

// find the second point on the circumference that is orthogonal
// to the line intersecting the two circle origos
var start2 : Point = new Point(point1.x + Math.cos(ang - Math.PI / 2) * radius1, 
                               point1.y + Math.sin(ang - Math.PI/2)* radius1);
var end2 : Point = new Point(point2.x + Math.cos(ang - Math.PI / 2) * radius2,
                             point2.y + Math.sin(ang - Math.PI/2)* radius2);

// draw everything on the stage
this.graphics.lineStyle(1, 0x0);
this.graphics.drawCircle(point1.x, point1.y, radius1);
this.graphics.drawCircle(point2.x, point2.y, radius2);

this.graphics.moveTo(start1.x, start1.y);
this.graphics.lineTo(end1.x, end1.y);

this.graphics.moveTo(start2.x, start2.y);
this.graphics.lineTo(end2.x, end2.y);
于 2012-08-20T09:59:46.393 回答