Php 使用mysql查找矩形或圆形中的点
我有一个mysql数据库表,其中列出了坐标(x,y)的点 我想找到矩形内的点列表。如果矩形的任何一侧平行或垂直于任何轴对齐,这将非常简单。但事实并非如此。这意味着矩形是旋转的。 我还要找到圆内的点 矩形的已知数据 -所有四个点的坐标 圆的已知数据 -中心和半径的坐标 如何查询mysql表以查找矩形和圆形中的点Php 使用mysql查找矩形或圆形中的点,php,mysql,geometry,cartesian,Php,Mysql,Geometry,Cartesian,我有一个mysql数据库表,其中列出了坐标(x,y)的点 我想找到矩形内的点列表。如果矩形的任何一侧平行或垂直于任何轴对齐,这将非常简单。但事实并非如此。这意味着矩形是旋转的。 我还要找到圆内的点 矩形的已知数据 -所有四个点的坐标 圆的已知数据 -中心和半径的坐标 如何查询mysql表以查找矩形和圆形中的点 如果有关系,那么我使用的前端是PHP。一个矩形可以由两个表示对角的点定义,例如:A(x,y)和B(x,y)。如果要测试点C(x,y)是否位于矩形内,则: IF( (Cx BETWEEN A
如果有关系,那么我使用的前端是PHP。一个矩形可以由两个表示对角的点定义,例如: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²)
因此:
假设包含x和y值的列被编入索引,这可能比简单地进行数学运算少占用几个CPU周期,但这是有争议的,我倾向于称之为wash
至于循环,你不可能比
WHERE
SQRT( POW(ABS($Cx - x),2) + POW(ABS($Cy - y),2) ) < $radius
在哪里
SQRT(功率(ABS($Cx-x),2)+功率(ABS($Cy-y),2))<$radius
你太关心这些计算的感知成本了,只需编写代码并使其工作即可。这不是执行这种琐碎优化的阶段。要补充@Sammitch的答案的一点是,如果你在世界地图上查看纬度和经度,计算哈弗斯线距离(在球面上计算距离,因为地球是球体;) 下面是一个用于计算的普通Javascript示例:
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;
}
编辑->
以下是我编写的php版本:
function toRad($x) {
return $x * pi() / 180;
}
function calculateHaversineDistance($lat1, $lon1, $lat2, $lon2) {
$R = 6371; // km
$dLat = $this->toRad($lat2-$lat1);
$dLon = $this->toRad($lon2-$lon1);
$lat1 = $this->toRad($lat1);
$lat2 = $this->toRad($lat2);
$a = sin($dLat/2) * sin($dLat/2) +
sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
return $R * $c;
}
我知道这些公式,但我需要知道的是,我可以编写一个存储过程或一个查询,通过它我可以传递已知的参数,并得到该区域内的点列表。这是否可能使用php+mysql。他的矩形显然是旋转的,因此您的inRectangle代码无法工作。必须旋转它,使其与Y轴垂直,这将是非常痛苦的。我不想调用所有点并分析每个点,因为点列表非常广泛。@Vishak,除非你想到的圆和矩形总是相同的,你可以预先计算并存储结果,否则,就没有可能的方法只是神奇地知道。您可能可以通过过滤掉距离任何测试点超过X个单位的点来减少实际处理的点数,其中X足够大,但这可能需要与实际处理它们一样多的数学运算,而这并不多。数学是计算机的全部工作,他们很擅长数学。谢谢。编辑有帮助。我的想法是一样的。我计划从矩形顶点获取max x、max y、min x和min y,以创建另一个围绕所需矩形的矩形,并获取主矩形内的所有点,然后仅在这些返回点上运行函数,消除其余点。通过具有四个条件的查询(max x、min x、min y和maxy),获取主矩形中的点将非常简单。对于一个圆,我想用同样的方法在它周围创建一个正方形。我不想调用所有的点并分析每个点,因为点的列表很广泛,可以用其他方法吗?
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;
}
function toRad($x) {
return $x * pi() / 180;
}
function calculateHaversineDistance($lat1, $lon1, $lat2, $lon2) {
$R = 6371; // km
$dLat = $this->toRad($lat2-$lat1);
$dLon = $this->toRad($lon2-$lon1);
$lat1 = $this->toRad($lat1);
$lat2 = $this->toRad($lat2);
$a = sin($dLat/2) * sin($dLat/2) +
sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
return $R * $c;
}