Skip to content

Instantly share code, notes, and snippets.

@rama-adi
Created April 28, 2023 05:46
Show Gist options
  • Save rama-adi/58ca514f9006b460254f6d8dd14e969e to your computer and use it in GitHub Desktop.
Save rama-adi/58ca514f9006b460254f6d8dd14e969e to your computer and use it in GitHub Desktop.
A PHP class to check if a set of vertices is inside a polygon.

PolygonChecker PHP Class

PolygonChecker is a PHP class that can be used to check if a set of vertices lies inside a polygon. It provides methods to set the polygon vertices and the dimensions of the polygon, and to check if a set of provided vertices lie inside the polygon.

Usage

Creating an instance To create an instance of PolygonChecker, use the create() method as follows:

$checker = PolygonChecker::create();

Setting the polygon vertices

The polygon vertices can be set using one of two methods:

  • withNormalizedVertices($normalizedVertices, $width, $height): This method takes an array of normalized vertices, where each vertex is an associative array with keys x and y, representing the x and y coordinates of the vertex. The method also takes the width and height of the polygon. The normalized vertices should have values between 0 and 1, representing the position of the vertices relative to the width and height of the polygon. This method returns the instance of PolygonChecker.
  • withDenormalizedVertices($denormalizedVertices): This method takes an array of denormalized vertices, where each vertex is an associative array with keys x and y, representing the x and y coordinates of the vertex. The method assumes that the vertices are already denormalized, i.e., their values are in pixels. This method returns the instance of PolygonChecker.

Checking if vertices are inside the polygon

To check if a set of provided vertices lie inside the polygon, use the areVerticesInside($providedVertices) method. This method takes an array of vertices, where each vertex is an associative array with keys x and y, representing the x and y coordinates of the vertex. The method returns true if all the provided vertices lie inside the polygon, and false otherwise.

Example

// Create an instance of PolygonChecker
$checker = PolygonChecker::create();

// Set the polygon vertices using normalized values
$normalizedVertices = [
    ["x" => 0.1, "y" => 0.1],
    ["x" => 0.1, "y" => 0.9],
    ["x" => 0.9, "y" => 0.9],
    ["x" => 0.9, "y" => 0.1],
];
$width = 640;
$height = 480;
$checker->withNormalizedVertices($normalizedVertices, $width, $height);

// Check if some provided vertices are inside the polygon
$providedVertices = [
    ["x" => 100, "y" => 100],
    ["x" => 100, "y" => 400],
    ["x" => 400, "y" => 400],
    ["x" => 400, "y" => 100],
];
$isInside = $checker->areVerticesInside($providedVertices);

if ($isInside) {
    echo "All provided vertices are inside the polygon.";
} else {
    echo "Some provided vertices are outside the polygon.";
}
<?php
/**
* Class PolygonChecker
*
* Represents a polygon shape and checks whether a set of vertices are inside the polygon.
*/
class PolygonChecker
{
private array $vertices;
private float $width;
private float $height;
/**
* Creates a new PolygonChecker instance.
*
* @return PolygonChecker The newly created instance.
*/
public static function create(): PolygonChecker
{
return new self();
}
/**
* Sets the normalized vertices of the polygon along with its width and height.
*
* @param array $normalizedVertices An array of normalized vertices.
* @param float $width The width of the polygon.
* @param float $height The height of the polygon.
*
* @return $this The current instance.
*/
public function withNormalizedVertices(array $normalizedVertices, float $width, float $height): self
{
$this->width = $width;
$this->height = $height;
$this->vertices = $this->denormalizeVertices($normalizedVertices);
return $this;
}
/**
* Sets the denormalized vertices of the polygon.
*
* @param array $denormalizedVertices An array of denormalized vertices.
*
* @return $this The current instance.
*/
public function withDenormalizedVertices(array $denormalizedVertices): self
{
$this->vertices = $denormalizedVertices;
return $this;
}
/**
* Converts the normalized vertices of the polygon to denormalized vertices.
*
* @param array $normalizedVertices An array of normalized vertices.
*
* @return array The array of denormalized vertices.
*/
private function denormalizeVertices(array $normalizedVertices): array
{
$denormalizedVertices = [];
foreach ($normalizedVertices as $vertex) {
$denormalizedVertices[] = [
"x" => $vertex["x"] * $this->width,
"y" => $vertex["y"] * $this->height,
];
}
return $denormalizedVertices;
}
/**
* Checks if a given point is inside the polygon.
*
* @param array $point The point to check.
* @param array $polygon The array of polygon vertices.
*
* @return bool Whether the point is inside the polygon or not.
*/
private function isPointInPolygon(array $point, array $polygon): bool
{
$c = false;
$numVertices = count($polygon);
for ($i = 0, $j = $numVertices - 1; $i < $numVertices; $j = $i++) {
if (((($polygon[$i]["y"] > $point["y"]) != ($polygon[$j]["y"] > $point["y"])) &&
($point["x"] < ($polygon[$j]["x"] - $polygon[$i]["x"]) * ($point["y"] - $polygon[$i]["y"]) / ($polygon[$j]["y"] - $polygon[$i]["y"]) + $polygon[$i]["x"]))) {
$c = !$c;
}
}
return $c;
}
/**
* Checks if all the provided vertices are inside the polygon.
*
* @param array $providedVertices An array of vertices to check.
*
* @return bool Whether all the provided vertices are inside the polygon or not.
*/
public function areVerticesInside(array $providedVertices): bool
{
foreach ($providedVertices as $vertex) {
if (!$this->isPointInPolygon($vertex, $this->vertices)) {
return false;
}
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment