从一点到圆上的相对切线画一条线? AS3 中的圆锥/楔形
这应该是一些简单的几何图形:如何计算在下面的代码中绘制线条的点,以便它形成 2D 圆锥形或楔形形状?
import flash.geom.Point;
//draw circle
var mc=new Sprite()
mc.graphics.lineStyle(0,0)
mc.graphics.drawCircle(0,0,30)
mc.x=mc.y=Math.random()*300+100
addChild(mc)
//draw lines:
graphics.lineStyle(0,0)
var p=new Point(Math.random()*500,Math.random()*400)
graphics.moveTo(p.x, p.y)
graphics.lineTo(mc.x,mc.y) // << should be point on edge of circle
graphics.moveTo(p.x, p.y)
graphics.lineTo(mc.x,mc.y) // << should be point on opposite edge of circle
更新:
谢谢大家,我应该提到我的目标不是绘制楔形,而是从随机点到现有圆的边缘绘制一条线。
如果您对代数比对动作脚本更熟悉,也许您可以看看这个图形并为我发布一个公式?
This should be a bit of simple geometry: How do I calculate the points to draw the lines in the code below so that it makes a 2D cone or wedge shape?
import flash.geom.Point;
//draw circle
var mc=new Sprite()
mc.graphics.lineStyle(0,0)
mc.graphics.drawCircle(0,0,30)
mc.x=mc.y=Math.random()*300+100
addChild(mc)
//draw lines:
graphics.lineStyle(0,0)
var p=new Point(Math.random()*500,Math.random()*400)
graphics.moveTo(p.x, p.y)
graphics.lineTo(mc.x,mc.y) // << should be point on edge of circle
graphics.moveTo(p.x, p.y)
graphics.lineTo(mc.x,mc.y) // << should be point on opposite edge of circle
UPDATE:
Thanks guys, I should have mentioned my aim is not to draw a wedge shape, but to draw a line from a random point to the edge of an existing circle.
If you're more comfortable with algebra than actionscript, maybe you could have a look at this graphic and post a formula for me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的问题是关于泰勒斯定理(请参阅http://en.wikipedia.org/wiki/Thales% 27_定理)。
以下是稍加修改以适用于 AS3 的定理。
导入 flash.geom.Point;
最终产品:
绘制第二个圆圈(实际上不需要在第二个圆圈中绘制) ,您只需要它的中心点和半径)
查看以下 SWF 以查看实际效果(刷新即可查看不同的随机圆圈):
http://megaswf.com/serve/1097652
Your question is about Thales theorem (see http://en.wikipedia.org/wiki/Thales%27_theorem).
The following is the theorem modified slightly to work with AS3.
import flash.geom.Point;
The final product:
With the second circle drawn (you don't actually need to draw in the second circle, you just need its center point and radius)
Checkout the following SWF to see in action (refresh to see different random circles):
http://megaswf.com/serve/1097652
令
(xP, yP)
为切线的交点,(xC,yY)
为圆心,您要在其中寻找坐标( xT,yT)
的切点。此外,令T
为切线向量,R
为半径向量。由于它们是垂直的,因此您有R 。 T = 0
。这让我们
设
r
为圆的半径,并设x:=xT-xC, y:=yT-yC, xp:=xP-xC, yp:=yP-yC
(基本上,我们将圆移动到(0,0)
中)。切点位于圆上,因此有
x²+y²=r²
,因此也有y=sqrt(r²-x²)
。应用于上述方程的变量替换为我们提供:
使用我们拥有的圆信息:
这是一个二次方程 有 0、1 或 2 个解决方案。如果 P 在圆内,则为 0;如果 P 在圆上,则为 1;如果 P 在圆外,则为 2。
我不会在这里给出明确的解决方案,因为它是一个非常糟糕的公式,并且如果您将此处引入的变量映射到代码中的变量,则编写起来会容易得多:
祝您好运,因为我非常糟糕微积分,再加上现在是 04:00,所以你可以打赌,某处有错误,但它应该会让你走向正确的方向;)
Let
(xP, yP)
be the intersection of the tangents,(xC,yY)
be the center of the circle, where you are looking for the coordinates(xT,yT)
of the tangent points. Further more letT
be the vector of the tangent andR
be the vector of the radius. Since they are perpendicular, you haveR . T = 0
.This gives us
Let
r
be the radius of the circle and letx:=xT-xC, y:=yT-yC, xp:=xP-xC, yp:=yP-yC
(basically, we move the circle into(0,0)
).The tangent point is on the circle, so you have
x²+y²=r²
and thus alsoy=sqrt(r²-x²)
.The variable substitution applied to the above equation gives us:
Using the circle information we have:
This is a quadratic equation with 0, 1 or 2 solutions. 0, if P is in the circle, 1, if P is on the circle and 2, if P is outside the circle.
I won't put the explicit solution here, since it's a hell of a formula and it's a lot easier to write, if you map the variables introduced here to variables in your code as:
Best of luck with this, because I am very bad with calculus, plus it's 04:00 here, so you can bet, there's a mistake somewhere, but it should get you in the right direction ;)
将点表示为 P,圆心表示为 M,圆上的切点表示为 X。 三角形 PMT 是直角三角形。当你浏览它时,你可能想在纸上画出草图,以便更容易理解。
X的位置就是M的位置加上X的径向向量,即边MX。接下来的计算就是计算向量 MX。
向量 MX 可以分解为两个垂直分量。一种与 MP 平行,另一种与 MP 垂直。首先要做的是获得这两个方向的单位向量。第一个很简单,因为它只是 MP 的标准化版本。通过交换分量并取反一个分量,可以在 2D 中轻松获得与此垂直的向量。您否定哪个分量在这里无关紧要,因为您最终需要两条切线。
现在我们有了两个单位向量,我们需要计算出每个单位向量需要多少来创建径向向量 MX。用 theta 表示角度 PMX,我们可以从简单的直角三角形得到 cos(theta)=r/|MP|其中 r 是圆的半径,|MP|是 MP 的长度(您已经计算出上面的单位向量)。
从 X 到 MP 的垂线会得到另一个涉及 theta 的直角三角形,其对边和邻边代表我们想要的两个分量。这些边的长度在 MP 方向上为 r * cos(theta),在垂直方向上为 r * sin(theta)。
因此,您的最终结果本质上是
X = M + r * cos(theta) * unit_MP + r * sin(theta) * unit_MP_perp_1
对于切点之一,并且
X = M + r * cos(theta) * unit_MP + r * sin (theta) * unit_MP_perp_2
为另一个。 Unit_MP 和unit_MP_perp_1/2 是我们之前计算出的单位向量。 perp 向量的 1/2 版本对应于交换后对第一或第二分量取反。
编辑
根据您添加的图表,方程变为
x1 = cx + R * cos(theta) * Ux + R * sin(theta) * U1x
y1 = cy + R * cos(theta) * Uy + R * sin(theta) * U1y
具有类似的方程 (x2,y2)。在这些方程中
cos(theta) = r / D
sin(theta) = A / D
其中 D = sqrt( (px - cx )^2 + (py - cy)^2 )
且
Ux = (px -cx) / D
Uy = (py -cy) / D
因此
U1x = -Uy
U1y = Ux
另一个切点的垂直单位向量为
U2x = Uy
U2y =-Ux
Denote your point as P, the circle centre as M, and the tangent point on the circle as X. Triangle PMT is a right-angled triangle. You might want to sketch this out on paper as you go through it to make it easier to follow.
The position of X is just the position of M plus the radial vector to X i.e. the edge MX. The calculation is then about computing the vector MX.
The vector MX can be decomposed into two perpendicular components. One that is parallel to MP and one that is perpendicular to MP. The first thing to do is obtain unit vectors in those two directions. The first is easy as it's just the normalised version of MP. A perpendicular vector to this is easily obtained in 2D by swapping the components and negating one component. Which component you negate is irrelevant here since you ultimately want both tangent lines.
Now that we have our two unit vectors we need to work out how much of each is required to create the radial vector MX. Denoting the angle PMX by theta we have from simple right-angled triangles that cos(theta)=r/|MP| where r is the radius of your circle and |MP| is the length of MP (which you already calculated to get your unit vector above).
Dropping a perpendicular from X to MP gives another right-angled triangle involving theta whose opposite and adjacent sides represent the two components we want. The lengths of these sides are just r * cos(theta) in the MP direction and r * sin(theta) in the perpendicular direction.
So your final result is essentially
X = M + r * cos(theta) * unit_MP + r * sin(theta) * unit_MP_perp_1
for one of the tangent points and
X = M + r * cos(theta) * unit_MP + r * sin(theta) * unit_MP_perp_2
for the other. Unit_MP and unit_MP_perp_1/2 are the unit vectors we worked out earlier. The 1/2 version of the perp vector correspond to negating either the first or second components after the swap.
Edit
In terms of the diagram you added, the equation becomes
x1 = cx + R * cos(theta) * Ux + R * sin(theta) * U1x
y1 = cy + R * cos(theta) * Uy + R * sin(theta) * U1y
with similar equations (x2,y2). In these equations
cos(theta) = r / D
sin(theta) = A / D
where D = sqrt( (px - cx )^2 + (py - cy)^2 )
and
Ux = (px -cx) / D
Uy = (py -cy) / D
and so
U1x = -Uy
U1y = Ux
The perpendicular unit vector for the other tangent point would be
U2x = Uy
U2y =-Ux
graphics.curveTo(controlX,ControlY,endX,endY);
在当前点和终点 (x,y) 之间绘制贝塞尔曲线,其中 control (x,y) 是曲线弯曲的点(例如Photoshop 中的钢笔工具)。设置为一半 delta X 并使用 Y 调整其强度。
graphics.curveTo(controlX,ControlY,endX,endY);
Draws a Bézier between current point and end (x,y) with control (x,y) being the point the curve is bent towards (like the pen tool in Photoshop). Set to half delta X and use Y to adjust its strength.
这是绘制 2D 楔形形状的片段。您可以调整
startAngle
和angle
变量来控制楔形的角度。半径将决定形状的宽度。这应该在 Shape、Sprite、MovieClip 或某些具有图形对象的子类中使用。Here is a snippet for drawing a 2D Wedge shape. You can adjust the
startAngle
andangle
vars to control the angle of the wedge. Radius will determine the width of the shape. This should be used within either a Shape, Sprite, MovieClip or some sub-class that has a graphics object.