根据丹尼尔的说法,在他的回答中,没有简单的方法来修改下面的功能,所以我咬了一下子弹并从头开始。解决方案如下(作为答案)。实际上,忽略我的回答。看到汤姆·西格达斯的答案,它缩短了很多。
我需要修改这里找到的解决方案:Calculate a vector from the center of a square to edge based on radius,它从矩形的中心计算向量,以适用于矩形内的任何点。
这是以前的解决方案,来自链接:
double magnitude;
double abs_cos_angle= fabs(cos(angle));
double abs_sin_angle= fabs(sin(angle));
if (width/2*abs_sin_angle <= height/2*abs_cos_angle)
{
magnitude= width/2/abs_cos_angle;
}
else
{
magnitude= height/2/abs_sin_angle;
}
double check_x= x + cos(angle)*magnitude;
double check_y= y + sin(angle)*magnitude;
check_x和check_y返回矩形边缘上的点,从中心以角度绘制的线将相交。
我去学校已经有一段时间了,所以我盲目地尝试用我感兴趣的点替换width / 2和height / 2.不幸的是,这不起作用。
有什么想法吗?
ETA:
如果线与顶部或左侧的矩形相交,则此盲修改始终返回正确的结果。根据原点所在的象限,当线与右或底相交时,它返回的点太远或太近。
答案 0 :(得分:4)
假设矩形由(x1,y1,x2,y2)定义,让我们说光线从(px,py)开始。
设vx = cos(角度)
让vy = sin(角度)
沿着光线行进t的距离将带您到达该点(px + t vx,py + t vy)。
沿着光线旅行,
因此,t有四种可能的解决方案。 t的正确值(在四个中)是最小的正。实际交点位于该点(px + t vx,py + t vy)。小心不要除以零!
答案 1 :(得分:1)
最简单的解决方案可能只是执行四个射线线段交叉测试。我怀疑专用解决方案会更有效或更容易理解和维护。
答案 2 :(得分:0)
让我们直接澄清一件事:听起来像是你担心2D中的矢量。你的所有积分都在飞机上。这是一个你感兴趣的矩形也是如此(四角,都是90度角,两对相对的长度相同)?
矩形的中心由四个角点的平均值给出:
alt text http://www.equationsheet.com/latexrender/pictures/ccdca519c24bb6ab2b6164144645572a.gif
alt text http://www.equationsheet.com/latexrender/pictures/84550340ace7dade26dc3294fef8e156.gif
你的矢量有起点。
任何矢量都由两个点定义,因此您只需要第二个点(例如,边缘的中点)来计算2D空间中的矢量:
alt text http://www.equationsheet.com/latexrender/pictures/7c680a2354f4a2a0d05d6c97ba949bc4.gif
从中心点和角度开始的问题在于它为您提供了无限数量的向量,而不仅仅是一个向量。 (沿着以给定角度穿过中心点的线有无数个终点。)你必须从那个无限集中挑选出你感兴趣的精确终点。如果恰好是在任意点与你的一条边相交的那条,你必须先计算它。这是沿着矢量线的根发现问题。也许你可以查看割线或其他数值方法来弄清楚如何去做。
答案 3 :(得分:0)
以下解决方案为穿过所提供的点的线构建公式,并以指定的角度穿过矩形边框。根据角度,我测试它是否与2个矩形边框中的任何一个相交。我总是根据0到90度的角度进行检查。为了解释这一点,象限Q2和Q4中的测试使用的线与Q1和Q4中的线垂直。
当角度= 0时,线条指向东方 我从360减去了角度,使线条顺时针旋转而不是逆时针旋转。
Private Function GetIntersectionPoint(ByVal rectangleSize As SizeF, ByVal p As Point, ByVal degreeAngle As Single) As PointF
Dim w = CInt(rectangleSize.Width)
Dim h = CInt(rectangleSize.Height)
degreeAngle = ((360 - degreeAngle) Mod 360)
If degreeAngle = 0 Then
Return New Point(w, p.Y)
ElseIf degreeAngle = 90 Then
Return New Point(p.X, 0)
ElseIf degreeAngle = 180 Then
Return New Point(0, p.Y)
ElseIf degreeAngle = 270 Then
Return New Point(p.X, h)
End If
Dim x, y As Integer
If (degreeAngle > 0 AndAlso degreeAngle < 90) Then
y = YFromX(degreeAngle, w, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(w, -y)
End If
x = XFromY(degreeAngle, 0, p)
Return New Point(x, 0)
End If
If (degreeAngle > 90 AndAlso degreeAngle < 180) Then
degreeAngle -= 90
y = YFromX_Perpedicular(degreeAngle, 0, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(0, -y)
End If
x = XFromY_Perpendicular(degreeAngle, 0, p)
Return New Point(x, 0)
End If
If (degreeAngle > 180 AndAlso degreeAngle < 270) Then
degreeAngle -= 180
y = YFromX(degreeAngle, 0, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(0, -y)
End If
x = XFromY(degreeAngle, -h, p)
Return New Point(x, h)
End If
If (degreeAngle > 270 AndAlso degreeAngle < 360) Then
degreeAngle -= 270
y = YFromX_Perpedicular(degreeAngle, w, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(w, -y)
End If
x = XFromY_Perpendicular(degreeAngle, -h, p)
Return New Point(x, h)
End If
End Function
Private Function YFromX(ByVal degreeAngle As Single, ByVal x As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt(sinAlpha / cosAlpha * (x - p.X) - p.Y)
End Function
Private Function XFromY(ByVal degreeAngle As Single, ByVal y As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt(cosAlpha / sinAlpha * (y + p.Y) + p.X)
End Function
Private Function YFromX_Perpedicular(ByVal degreeAngle As Single, ByVal x As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt((cosAlpha / sinAlpha) * (p.X - x) - p.Y)
End Function
Private Function XFromY_Perpendicular(ByVal degreeAngle As Single, ByVal y As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt(p.X - sinAlpha / cosAlpha * (y + p.Y))
End Function
答案 4 :(得分:0)
你基本上要求矩形的极坐标方程,它是
r(t) = min(R, w*abs(sec(t)), h*abs(csc(t))); t = [0, 2pi]
其中w和h是半宽和半高,R是大于或等于sqrt(w ^ 2 + h ^ 2)的任何数。这假定矩形位于原点,如果不是,则所有要做的就是将中心的坐标添加到结果中,通过(r cos(t),r sin获得结果) T))。 当然,这种方法很糟糕,因为sec和csc有奇点,但是你可以用max(w,h)来限制它们。