dou29106 2013-09-18 14:19
浏览 45
已采纳

查找重叠方块的所有点

The setup:

    a. 2D surface
    b. points (with x, y coordinates) which when connected form squares.
    c. I found an algorithm that finds the intersection points of those squares so assume we have them as well.

The question is: how do I get points that contour the squares.

I've included an image for better understanding.

contour example

I was looking into http://en.wikipedia.org/wiki/Convex_hull_algorithms but it seems like they all skip those intersections (the 90' angles).

I am writing this in php but i'd love to even see a pseudo code if at all possible.

  • 写回答

1条回答 默认 最新

  • doucheng2210 2014-03-31 20:34
    关注
    <?php
    //WARNING! we assume coords as non-polar. for this to work on large-scale, you need to convert polar into decard coords.
    //Can be done outside this script.
    
    //Points sample:
    $points_raw=json_decode('{"1":[[41.014357690351,-73.73715475406],[41.029170309649,-73.73715475406],[41.014357690351,-73.75644124594],[41.029178309649,-73.73721675406],[41.014365690351,-73.75650324594],[41.031554690351,-73.73806375406],[41.046091309649,-73.78489424594],[41.014688690351,-73.78819424594],[41.012691690351,-73.75993275406],[41.012691690351,-73.77921924594],[41.015809690351,-73.75893475406],[41.053689309649,-73.76006575406],[41.053689309649,-73.77935224594],[41.050793309649,-73.78376624594],[41.043862309649,-73.79638424594],[41.029049690351,-73.79638424594],[41.019350690351,-73.79608224594],[41.033268690351,-73.73637875406],[41.048081309649,-73.73637875406],[41.048081309649,-73.75566524594],[41.014365690351,-73.75644124594],[41.029170309649,-73.73721675406],[41.018165690351,-73.75650324594],[41.029178309649,-73.74662775406],[41.031554690351,-73.74662775406],[41.033268690351,-73.73806375406],[41.043862309649,-73.78489424594],[41.019350690351,-73.78819424594],[41.015809690351,-73.75993275406],[41.014688690351,-73.77921924594],[41.018165690351,-73.75893475406],[41.047266309649,-73.76006575406],[41.050793309649,-73.77935224594],[41.046091309649,-73.78376624594],[41.029049690351,-73.79608224594],[41.047266309649,-73.75566524594]]}',1);
    
    
    //BEGIN HERE:
    $points=$points_raw[1];
    
    function to_round($val)
    {
        //here we can try conversion from polar to decard. not sure if will work
        //no conversion for now, but just rounding for comparsion
        return round($val*1000000000000);
    }
    
    
    function sort_points_array($a, $b, $which)
    {
        $da=to_round($a[$which]);
        $db=to_round($b[$which]);
    
        if ($da == $db) {
            return 0;
        }
        return ($da < $db) ? -1 : 1;
    }
    
    function sort_by_0($a, $b)
    {
        return sort_points_array($a, $b, 0);
    }
    
    function sort_by_1($a, $b)
    {
        return sort_points_array($a, $b, 1);
    }
    
    //BEGIN OF UNOPTIMIZED SORT
    
    //sort by columns from left to right (does not have to be left/right on the map)
    //but we will try :) 0 -> Y, 1 -> X
    //sort by X, so lower X will be on top of array.
    //and each point in those columns will be also sorted from top to bottom by their Y
    
    usort($points,"sort_by_1");
    
    //then foreach to split array by "columns";
    $column_counter=0;
    $point_columns=array();
    $point_columns[$column_counter][]=$points[0];
    foreach($points as $n_point=>$p_coords)
    {
        if($n_point>0)
        {
            if(to_round($p_coords[1]) > to_round($point_columns[$column_counter][1][1]))
                    $column_counter++;
            $point_columns[$column_counter][]=$p_coords;
        }
    }
    
    //now sort each column
    $sorted_point_columns=array();
    foreach($point_columns as $pcn => $p_column)
    {
        usort($p_column,"sort_by_0");
        $sorted_point_columns[$pcn]=$p_column;
    }
    
    //SAME TO MAKE sorted_point_rows
    usort($points,"sort_by_0");
    
    $row_counter=0;
    $point_rows=array();
    $point_rows[$row_counter][]=$points[0];
    foreach($points as $n_point=>$p_coords)
    {
        if($n_point>0)
        {
            if(to_round($p_coords[0]) > to_round($point_rows[$row_counter][0][0]))
                    $row_counter++;
            $point_rows[$row_counter][]=$p_coords;
        }
    }
    $sorted_point_rows=array();
    foreach($point_rows as $prn => $p_row)
    {
        usort($p_row,"sort_by_1");
        $sorted_point_rows[$prn]=$p_row;
    }
    
    
    // END OF UNOPTIMIZED SORT
    
    //output array
    $final_points_poly=array();
    
    //clearly first point will be from 1st row;
    //and we will go to the RIGHT in current row to find next point
    $final_points_poly[0]=$sorted_point_rows[0][0];
    
    //and let the magic begin:
    $finished=false;
    $last_point_index=0;
    $points_total=count($points);
    $pos_x=0; //pos by columns
    $pos_y=0; //pos by rows
    
    $relative_X=0; //relative X position in current ROW;
    $relative_Y=0; //relative Y position in current COLUMN;
    
    $rule=1; // right / down = 1, left / up = -1
    
    //detect if we go by X or Y
    $going_Y=false;
    $finished=false;
    
    while(!$finished)
    {
        if($going_Y)
        {
            $relative_Y+=$rule;
            $last_point_index+=1;
            $cur_p=$sorted_point_columns[$pos_x][$relative_Y];
            $final_points_poly[$last_point_index]=$cur_p;
            $going_Y = !$going_Y;
            //search for pos_y:
            foreach($sorted_point_rows as $cur_y => $row)
            {
                if(to_round($row[0][0]) == to_round($cur_p[0]))
                {
                    $pos_y=$cur_y;
    
                    //search for relative_X
                    foreach($row as $cur_rel_x => $check_point)
                    {
                        if(to_round($check_point[1]) == to_round($cur_p[1]))
                        {
                            $relative_X=$cur_rel_x;
                            $rule = ($relative_X % 2 == 0 ? 1 : -1);
                            break 2;
                        }
    
                        //error_check 1
                        if($cur_rel_x == count($row)-1)
                            echo "error with calculating relative_X! check your data!
    ";
                    }
                }
                //error_check 2
                if($cur_y == count($sorted_point_rows)-1)
                    echo "error with calculating pos_y! check your data!
    ";
            }
        }
        else
        {
            $relative_X+=$rule;
            $last_point_index+=1;
            $cur_p=$sorted_point_rows[$pos_y][$relative_X];
            $final_points_poly[$last_point_index]=$cur_p;
            $going_Y = !$going_Y;
            //search for pos_x:
            foreach($sorted_point_columns as $cur_x => $column)
            {
                if(to_round($column[0][1]) == to_round($cur_p[1]))
                {
                    $pos_x=$cur_x;
    
                    //search for relative_Y
                    foreach($column as $cur_rel_y => $check_point)
                    {
                        if(to_round($check_point[0]) == to_round($cur_p[0]))
                        {
                            $relative_Y=$cur_rel_y;
                            $rule = ($relative_Y % 2 == 0 ? 1 : -1);
                            break 2;
                        }
    
                        //error_check 1
                        if($cur_rel_y == count($column)-1)
                            echo "error with calculating relative_Y! check your data!
    ";
                    }
                }
                //error_check 2
                if($cur_x == count($sorted_point_columns)-1)
                    echo "error with calculating pos_x! check your data!
    ";
            }
    
        }
    
        if($last_point_index == $points_total-1)
        {
            $finished=true;
        }
    }
    
    echo "all points:
    ";
    print_r($final_points_poly);
    
    /*
    //generate markers for google mapping
    
    $out = "var bbs=[];var markers=[];";
    $out .= "var pinI = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|ADDE63');";
    $out .= "var pinI2 = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|FF8C00');";
    $out .= "var pinI3 = new google.maps.MarkerImage('http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|990099');";
    
    $out .= "bbs.push(new google.maps.Polyline({ ";
    $out .= "path: [";
    
    foreach($final_points_poly as $m){
            $out .= "new google.maps.LatLng(".join(",",$m)."),";
    }
    
    $out .= "],";
    $out .= "strokeColor: 'black', strokeOpacity: 0.4, strokeWeight: 1 }));";
    
    $f = fopen("bbs.js",'w');
    fwrite($f,$out);
    fclose($f);
    */
    
    ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 来真人,不要ai!matlab有关常微分方程的问题求解决,
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算