Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotate method #123

Open
mstenta opened this issue Mar 3, 2016 · 1 comment
Open

Rotate method #123

mstenta opened this issue Mar 3, 2016 · 1 comment

Comments

@mstenta
Copy link

mstenta commented Mar 3, 2016

Feature request: add a rotate() method to the Geometry class that allows geometries to be rotated by a given angle around their centroid point.

@mstenta
Copy link
Author

mstenta commented Mar 9, 2016

Here are two functions I wrote (outside of GeoPHP) for rotating a point and a polygon around an origin point. I'm using these in my farm management software - but ultimately they should probably be included in GeoPHP as methods for each class. So we'll also need to write the code for LineStrings, Collections, etc.

Also note: these include BCMath code as well. See #114 and #115

/**
 * Rotate a polygon around an origin.
 *
 * @param $polygon
 *   A Polygon geometry object.
 * @param $origin
 *   An origin point to rotate around.
 * @param $angle
 *   The angle of rotation, in degrees.
 *
 * @return \Polygon
 *   Returns a Polygon geometry object that has been rotated around an origin.
 */
function rotate_polygon($polygon, $origin, $angle) {

  // If the geometry is not a polygon, bail.
  if ($polygon->geometryType() != 'Polygon' || $polygon->components[0]->geometryType() != 'LineString') {
    return $polygon;
  }

  // Iterate through the polygon's points, and rotate each around the origin.
  $linestring = $polygon->components[0];
  $new_points = array();
  if (!empty($linestring->components)) {
    foreach ($linestring->components as $point) {
      $new_points[] = farm_crop_bed_former_rotate_point($point, $origin, $angle);
    }
  }

  // Return a new Polygon object.
  return new Polygon(array(new LineString($new_points)));
}

/**
 * Rotate a point around an origin.
 *
 * @param $point
 *   A Point geometry object.
 * @param $origin
 *   An origin point to rotate around.
 * @param $angle
 *   The angle of rotation, in degrees.
 *
 * @return \Point
 *   Returns a Point geometry object that has been rotated around an origin.
 */
function rotate_point($point, $origin, $angle) {

  // If $point and $origin are not points, or $angle is not an integer between
  // 0 and 359, bail.
  if ($point->geometryType() != 'Point' || $origin->geometryType() != 'Point' || $angle < 0 || $angle > 359) {
    return $point;
  }

  // Convert the angle to radians.
  $angle = deg2rad($angle);

  // Calculate the new rotated points.
  if (geoPHP::bcmathInstalled()) {
    $x = bcadd($origin->x(), bcsub(bcmul(bcsub($point->x(), $origin->x()), cos($angle)), bcmul(bcsub($point->y(), $origin->y()), sin($angle))));
    $y = bcadd($origin->y(), bcadd(bcmul(bcsub($point->x(), $origin->x()), sin($angle)), bcmul(bcsub($point->y(), $origin->y()), cos($angle))));
  }
  else {
    $x = $origin->x() + (($point->x() - $origin->x()) * cos($angle)) - (($point->y() - $origin->y()) * sin($angle));
    $y = $origin->y() + (($point->x() - $origin->x()) * sin($angle)) + (($point->y() - $origin->y()) * cos($angle));
  }

  // Return a new Point object.
  return new Point($x, $y);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant