溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

地圖區(qū)域劃分轉(zhuǎn)換成數(shù)學(xué)模型解決問題

發(fā)布時(shí)間:2020-07-07 18:31:37 來源:網(wǎng)絡(luò) 閱讀:582 作者:mrc_elite 欄目:開發(fā)技術(shù)

計(jì)算機(jī)與數(shù)學(xué)是息息相關(guān)的,計(jì)算機(jī)模型中無時(shí)無刻不體現(xiàn)數(shù)學(xué)的理念。例如余弦定理用來求兩個(gè)文案的相似度。今天我這里解決的問題也與數(shù)學(xué)有關(guān)。實(shí)際需求是這樣的,在項(xiàng)目當(dāng)中,需要人工在百度地圖中劃分配送區(qū)域,要求劃分出來的區(qū)域不能是雜亂無章的,即線段與線段之間不能相穿。當(dāng)時(shí)接到這個(gè)需求有點(diǎn)懵逼,如何是好,開完會坐下來,慢慢畫圖發(fā)現(xiàn)劃出的圖形只要是凹凸多邊形即可,突然茅塞頓開,問題迎刃而解,因?yàn)橐?guī)則的凹凸多邊形的頂點(diǎn)數(shù)與邊數(shù)相等,根據(jù)這段理念簡單寫了一段驗(yàn)證,結(jié)果驗(yàn)證無誤。

用對象的方式實(shí)現(xiàn)代碼邏輯:
<?php
/**
 * 平面點(diǎn)
 *
 * Class Point2D
 */
class Point2D
{
    public $x;
    public $y;

    public function __construct($x, $y)
    {
        $this->x = $x;
        $this->y = $y;
    }

    public function __toString()
    {
        return "({$this->x}, {$this->y})";
    }
}

/**
 * 平面線
 *
 * Class Line2D
 */
class Line2D
{
    /**
     * @var Point2D
     */
    public $p1;

    /**
     * @var Point2D
     */
    public $p2;

    public function __construct(Point2D $p1, Point2D $p2)
    {
        $this->p1 = $p1;
        $this->p2 = $p2;
    }

    public function __toString()
    {
        return "({$this->p1}, {$this->p2})";
    }
}

/**
 * 平面向量
 *
 * Class Vector
 */
class Vector extends Line2D
{
    /**
     * 向量
     *
     * @var Point2D
     */
    public $v;

    public function __construct(Point2D $p1, Point2D $p2)
    {
        parent::__construct($p1, $p2);

        $this->v = new Point2D($p2->x - $p1->x, $p2->y - $p1->y);
    }

    public function __toString()
    {
        return "({$this->p1}->{$this->p2})";
    }

    /**
     * 向量叉積
     *
     * @param Vector $v1
     * @param Vector $v2
     * @return Vector
     */
    public static function mul(Vector $v1, Vector $v2)
    {
        return $v1->v->x * $v2->v->y - $v2->v->x * $v1->v->y;
    }

}

public function checkMapIsRegular($aPoint)
{

       $aFormatPoint   = array();
       $aFormatLine    = array();
       try {
           if ($aPoint) {
               //拆分出坐標(biāo)點(diǎn),初始化坐標(biāo)對象
               foreach ($aPoint as $item) {
                   list($pointX,$pointY) = explode(',' ,$item);
                   $aFormatPoint[] = array('x' => $pointX, 'y' => $pointY);
               }

               //按順序構(gòu)成矢量線
               $index  = count($aFormatPoint) - 1;
               foreach ($aFormatPoint as $key=>$point) {
                   $aFormatLine[]['start'] = $point;
                   if ($index == $key) {
                       $aFormatLine[$key]['end']   = $aFormatPoint[0];
                   } else {
                       $aFormatLine[$key]['end']   = $aFormatPoint[$key+1];
                   }
               }

               $aOutPoint      = $aFormatLine;
               $edgeCount      = 0;
               $vertexCount    = count($aOutPoint);
               array_shift($aFormatLine);

               //兩兩求交點(diǎn)
               foreach ($aOutPoint as $key=>$aLine) {
                   if (empty($aFormatLine)) {
                       continue;
                   }
                   foreach ($aFormatLine as $innerKey => $aInnerLine) {
                       //初始化坐標(biāo)對象
                       $oAPointStart   = new Point2D($aOutPoint[$key]['start']['x'],$aOutPoint[$key]['start']['y']);
                       $oAPointEnd     = new Point2D($aOutPoint[$key]['end']['x'],$aOutPoint[$key]['end']['y']);
                       $oBPointStart   = new Point2D($aFormatLine[$innerKey]['start']['x'],$aFormatLine[$innerKey]['start']['y']);
                       $oBPointEnd     = new Point2D($aFormatLine[$innerKey]['end']['x'],$aFormatLine[$innerKey]['end']['y']);

                       //兩兩畫出矢量線
                       $vector         = new Vector($oAPointStart, $oAPointEnd);
                       $vABStart       = new Vector($oAPointStart, $oBPointStart);
                       $vABEnd         = new Vector($oAPointStart, $oBPointEnd);

                       $isInterSect1   = false;
                       $isInterSect2   = false;

                       if (Vector::mul($vABStart, $vector) * Vector::mul($vABEnd, $vector) <= 0) {
                           $isInterSect1   = true;
                       }

                       $oppositeVector = new Vector($oBPointStart, $oAPointStart);
                       $oVABStart      = new Vector($oBPointStart, $oAPointEnd);
                       $oVABEnd        = new Vector($oBPointStart, $oBPointEnd);

                       if (Vector::mul($oppositeVector, $oVABEnd) * Vector::mul($oVABStart, $oVABEnd) <= 0) {
                           $isInterSect2   = true;
                       }

                       if ($isInterSect1 && $isInterSect2) {
                           $edgeCount += 1;
                       }
                   }
                   array_shift($aFormatLine);
               }
           }

           if ($edgeCount == $vertexCount) {
               return true;
           } else {
               return false;
           }

       }catch (\Exception $e) {
           return $e->getMessage();
       }
}


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI