我试图确定一个点是否在来自原始点的两个角度之间(以确定是否使用 OpenGL 绘制它,尽管这无关紧要)。最简单的方法是什么?
问问题
889 次
5 回答
2
如果角度 CAB + BAD = 45 的绝对值,则点在内部。如果 CAB + BAD > 45,那么点在外面。
于 2012-12-29T19:26:14.290 回答
2
2 个向量u = (ux, uy
), v = (vx, vy)
, 的二维叉积是
u x v = ux * vy - uy * vx = |u| * |v| * sin(phi)
其中是到phi
之间的角度(从 到 测量u
)。如果角度在 0 到 180 度之间,则叉积为正。v
u
v
所以
(B - A) x (D - A) > 0
如果B
位于从A
到的向量“左侧”的半平面上D
,因此
(B - A) x (D - A) > 0 and (B - A) x (C - A) < 0
确切地说,如果B
位于该部门。如果您还想捕获B
位于扇区边界的情况,请使用>=
resp。<=
.
(注意:只要扇区的角度A
小于 180 度,此方法就有效,并且可能可以推广到更大的角度。由于您的角度是 45 度,因此可以使用这些公式。)
于 2012-12-29T19:46:46.880 回答
0
如果您有点坐标且没有角度,则使用极坐标将 [X,Y] -> [R,Theta](半径和角度)相对于中心(图中的 A)转换,然后比较角度(θ)。
此代码将 Point 转换为相对于中心点的 PolarPoint:
/// <summary>
/// Converts Point to polar coordinate point
/// </summary>
public static PolarPoint PointToPolarPoint(Point center, Point point)
{
double dist = Distance(center, point);
double theta = Math.Atan2(point.Y - center.Y, point.X - center.X);
if (theta < 0) // provide 0 - 2Pi "experience"
theta = 2 * Math.PI + theta;
return new PolarPoint(dist, theta);
}
/// <summary>
/// Calculates distance between two points
/// </summary>
public static int Distance(Point p1, Point p2)
{
return (int) Math.Sqrt
(
Math.Pow(p1.X - p2.X, 2) +
Math.Pow(p1.Y - p2.Y, 2)
);
}
C# 中的 Polar Point 类(包括转换回 Point):
/* NFX by ITAdapter
* Originated: 2006.01
* Revision: NFX 0.2 2009.02.10
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace NFX.Geometry
{
/// <summary>
/// Represents a point with polar coordinates
/// </summary>
public struct PolarPoint
{
#region .ctor
/// <summary>
/// Initializes polar coordinates
/// </summary>
public PolarPoint(double r, double theta)
{
m_R = r;
m_Theta = 0;
Theta = theta;
}
/// <summary>
/// Initializes polar coordinates from 2-d cartesian coordinates
/// </summary>
public PolarPoint(Point center, Point point)
{
this = CartesianUtils.PointToPolarPoint(center, point);
}
#endregion
#region Private Fields
private double m_R;
private double m_Theta;
#endregion
#region Properties
/// <summary>
/// R coordinate component which is coordinate distance from point of coordinates origin
/// </summary>
public double R
{
get { return m_R; }
set { m_R = value; }
}
/// <summary>
/// Angular azimuth coordinate component. An angle must be between 0 and 2Pi.
/// Note: Due to screen Y coordinate going from top to bottom (in usual orientation)
/// Theta angle may be reversed, that is - be positive in the lower half coordinate plane.
/// Please refer to:
/// http://en.wikipedia.org/wiki/Polar_coordinates
/// </summary>
public double Theta
{
get { return m_Theta; }
set
{
if ((value < 0) || (value > Math.PI * 2))
throw new NFXException("Invalid polar coordinates angle");
m_Theta = value;
}
}
/// <summary>
/// Returns polar coordinate converted to 2-d cartesian coordinates.
/// Coordinates are relative to 0,0 of the angle base vertex
/// </summary>
public Point Point
{
get
{
int x = (int)(m_R * Math.Cos(m_Theta));
int y = (int)(m_R * Math.Sin(m_Theta));
return new Point(x, y);
}
}
#endregion
#region Operators
public static bool operator ==(PolarPoint left, PolarPoint right)
{
return (left.m_R == right.m_R) && (left.m_Theta == right.m_Theta);
}
public static bool operator !=(PolarPoint left, PolarPoint right)
{
return (left.m_R != right.m_R) || (left.m_Theta != right.m_Theta);
}
#endregion
#region Object overrides
public override bool Equals(object obj)
{
if (obj is PolarPoint)
return this==((PolarPoint)obj);
else
return false;
}
public override int GetHashCode()
{
return m_R.GetHashCode() + m_Theta.GetHashCode();
}
public override string ToString()
{
return string.Format("Distance: {0}; Angle: {1} rad.", m_R, m_Theta);
}
#endregion
}
}
于 2012-12-29T19:31:12.820 回答
0
我最终把它归结为这个函数(其中cameraYR是点A旋转的角度,cameraX是Ax,cameraY是Ay,x是Bx,y是By):
float cameraAngle = PI + cameraYR;
float angle = PI / 2 + atan2f(cameraY - y, cameraX - x);
float anglediff = fmodf(angle - cameraAngle + PI, PI * 2) - PI;
return (anglediff <= visibleAngle && anglediff >= -visibleAngle) || (anglediff <= -PI * 2 + visibleAngle && angleDiff >= -PI * 2 - visibleAngle);
于 2012-12-30T09:15:44.800 回答
0
于 2013-02-25T15:49:52.453 回答