我有一个mysql数据库表,其中包含带有坐标(x,y)的列表点
我想找到落在矩形内的点列表。如果矩形的任何一侧与任何轴平行或垂直对齐,这将是简单的。但事实并非如此。这意味着矩形旋转。 我还必须找到一个圆圈内的点。
矩形的已知数据 - 协调所有四点 圆的已知数据 -Co-纵坐标为中心和半径。
如何查询mysql表以找到落在矩形和圆圈中的点?
如果重要,那么我使用的前端是PHP。
答案 0 :(得分:2)
矩形可以由表示相对角的两个点定义,例如:A(x,y)和B(x,y)。如果你有一个要测试的点C(x,y),看它是否在矩形内,那么:
IF( (Cx BETWEEN Ax AND Bx) AND (Cy BETWEEN Ay AND By) ) THEN
point C is in the rectangle defined by points A and B
ELSE
nope
ENDIF
圆可以由单个点C(x,y)和半径R定义。如果中心与点P(x,y)之间的距离D小于半径R,则它在内部圈子:
当然你还记得毕达哥拉斯的理论,对吗?
C² = A² + B² SO C = SQRT(A² + B²)
所以:
D = SQRT( ABS(Cx - Px)² + ABS(Cy - Py)²)
IF( D <= R ) THEN
point P is inside the circle with center C and radius R
ELSE
nope
ENDIF
检查点是否在多边形内的算法比我在SQL查询或存储过程中编写的算法要复杂一些,但这完全有可能。值得注意的是,它在恒定时间运行并且非常轻量级。 [需要大约6个算术运算,并且对于poly中的每个点可能需要2或3个逻辑运算]
为了减少所需的数字计算,你可以简单地编写你的选择以在粗略的边界框内获得点数,然后再进行处理:
WHERE
x BETWEEN MIN(x1,x2,x3,x4) AND MAX(x1,x2,x3,x4)
AND
y BETWEEN MIN(y1,y2,y3,y4) AND MAX(y1,y2,y3,y4)
假设包含x和y值的列被索引,这个可能使用比简单数学更少的CPU周期,但这是有争议的,我倾向于把它称为洗涤。 / p>
至于圆圈,你不可能比
更有效率WHERE
SQRT( POW(ABS($Cx - x),2) + POW(ABS($Cy - y),2) ) < $radius
你太在意这些计算的感知成本,只需编写代码并使其正常工作。这不是进行这种琐碎优化的阶段。
答案 1 :(得分:0)
要添加到@ Sammitch的答案,有一点是,如果您在世界地图上查看纬度和经度,则计算半长距离(球面上的距离计算,因为地球是球体;)https://en.wikipedia.org/wiki/Haversine_formula)< / p>
这是一个用于计算的香草Javascript示例:
subject = subject.doOnUnsubscribe(() -> L.LOGD(TAG, "Unsubcribed from subject!"));
编辑 - &GT;
这是我写的php版本:
function calculateHaversineDistance(lat1x, lon1, lat2x, lon2) {
var R = 6371; // km
var dLat = toRad(lat2x-lat1x);
var dLon = toRad(lon2-lon1);
var lat1 = toRad(lat1x);
var lat2 = toRad(lat2x);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
function toRad(x) {
return x * Math.PI / 180;
}