如何在循环遍历数组时找到圆圈中的区域

How to find a zone in a circle while looping through an array

我有一组行星及其经度:

$planets['Sun']['longitude']=9
$planets['Moon']['longitude']=341
$planets['Mercury']['longitude']=27
$planets['Venus']['longitude']=349

我有一个行星带阵列,称为 "houses",每个带经度将 360 度圆分成 12 个不相等的 "houses"。经度数字表示该区域的起始边界。

$houses[1]['longitude']=144
$houses[2]['longitude']=164
$houses[3]['longitude']=190
$houses[4]['longitude']=223
$houses[5]['longitude']=261
$houses[6]['longitude']=296
$houses[7]['longitude']=324
$houses[8]['longitude']=344
$houses[9]['longitude']=10
$houses[10]['longitude']=43
$houses[11]['longitude']=81
$houses[12]['longitude']=116

我想根据行星的经度为 return 特定行星的宫位创建一个函数。因此,例如,如果行星的经度为 170,那么它将位于第 2 宫,因为它大于第 2 宫的经度且小于第 3 宫的经度,如上面的数组所示。

我有以下函数可以根据经度获取行星的宫位。从上面的例子来看,它适用于月亮和 Mercury,但不适用于太阳和金星。这是因为下一个房子比上一个小,因为它是360圈的尽头。

function get_planet_house($houses,$in_long){
    for ($i=1;$i<12;$i++){
        if ($i<11){
            $next_long=$houses[$i+1]['longitude'];
        }
        else {
            $next_long=$houses[1]['longitude'];
        }
        if ($in_long>$houses[$i]['longitude']){
            if ($in_long<$next_long){
                $house=$i;
            }
        }
    }
    return $house;
}

所以如果我这样做:get_planet_house($houses,$planets['Moon']['longitude']) 它 returns 7。但是如果我对 $planets['Sun']['longitude'] 做同样的事情,它将 return 空白。

如何修改函数以与圆一起使用,以便让太阳和金星显示它们在第 8 宫?

我会对数组进行排序,然后这是一项非常简单的任务。此解决方案适用于太阳、月亮、金星和所有其他行星:

function get_planet_house( $houses, $in_long )
{
    asort( $houses );
    foreach ( array_keys( $houses ) as $key )
    {
        if ( $in_long < $houses [$key]["longitude"] )
        {
            return $key - 1;
        }
    }
    return $key;
}

如果您的 $houses 由于某种原因无法排序,您可以在逻辑中增加一点复杂性:

function get_planet_house(array $houses,$in_long)
{
    for($i=1;$i<=12;$i++)
    {
        $left=$houses[$i]["longitude"];
        $right=($i==12?$houses[1]["longitude"]:$houses[$i+1]["longitude"]);
        if(($left<=$right && $in_long>=$left && $in_long<$right) || ($left>$right && ($in_long>=$left || $in_long<$right)))
        {
            return $i;
        }
    }
    return 0;
}

3v4l fiddle

如果左边界小于右边界,则检查输入经度是否落在这两个边界之间;如果左边界大于右边界,那么你检查输入经度是否落在外面这两个边界。