您好,登錄后才能下訂單哦!
計(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(); } }
免責(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)容。