Source code for gifpgn.geometry

from typing import Tuple, Optional
from math import cos, sin, atan2, sqrt

from ._types import Coord


[docs] def rotate_around_point(point: Coord, radians: float, origin: Coord) -> Coord: """Rotates point around origin by radians :param Coord point: :param float radians: :param Coord origin: defaults to (0, 0) :return Coord: """ x, y = point ox, oy = origin qx = int(ox + cos(radians) * (x - ox) + sin(radians) * (y - oy) + 1e-14) qy = int(oy + -sin(radians) * (x - ox) + cos(radians) * (y - oy) + 1e-14) return Coord(qx, qy)
[docs] def angle_between_two_points(point1: Coord, point2: Coord) -> float: """Returns the angle of a line between two points in radians :param Coord point1: :param Coord point2: :return float: Radians """ x0, y0 = point1 x1, y1 = point2 return -atan2(y1-y0, x1-x0)
[docs] def shorten_line(c1: Coord, c2: Coord, pix: int) -> Tuple[Coord, Coord]: """Shortens a line between two points by set number of pixels from the second point :param Coord c1: :param Coord c2: :param int pix: :return Tuple[Coord,Coord]: """ dx: float = c2[0] - c1[0] dy: float = c2[1] - c1[1] length = sqrt(dx*dx+dy*dy) if length > 0: dx /= length dy /= length dx *= length-pix dy *= length-pix return (c1, Coord(int(c1[0]+dx), int(c1[1]+dy)))
[docs] def line_intersection(line1: Tuple[Coord, Coord], line2: Tuple[Coord, Coord]) -> Optional[Coord]: """Returns the intersection point of two lines of infinite length, or None if no intersection :param Tuple[Coord, Coord] line1: :param Tuple[Coord, Coord] line2: :return Optional[Coord]: """ xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0]) ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1]) def det(a, b): return a[0] * b[1] - a[1] * b[0] div = det(xdiff, ydiff) if div == 0: # no intersection return None d = (det(*line1), det(*line2)) x = det(d, xdiff) / div y = det(d, ydiff) / div return Coord(x, y)