import math import numpy as np from analyzer.epoint import EPoint, homogenize from analyzer.grid import transformPoint class Line(): def __init__(self,a,b): self.a=a self.b=b self.points={a,b} def getSortedPoints(self): return tuple(sorted(self.points)) def computeAngle(self,line): ab=self.a-self.b cd=line.a-line.b alpha=math.atan(ab.y/ab.x) gamma=math.atan(cd.y/cd.x) fi=max(alpha,gamma)-min(alpha,gamma) return min(fi,math.pi-fi) def intersect(self,line): p=self.toProjective() q=line.toProjective() return EPoint.fromProjective(np.cross(p,q)) def toProjective(self): return homogenize(np.cross(self.a.toProjective(),self.b.toProjective())) def transform(self,matrix): a=EPoint.fromProjective(transformPoint(self.a.toProjective(),matrix)) b=EPoint.fromProjective(transformPoint(self.b.toProjective(),matrix)) if a is None or b is None: return None return Line(a,b) def score(self,points): score=len(self.points) for a in self.points: closest=sorted(points,key=lambda b: a.dist(b))[:4] score+=sum(0.01 for b in closest if b in self.points) return score def __str__(self): return "({0},{1})".format(self.a,self.b) def __repr__(self): return "Line({0},{1})".format(repr(self.a),repr(self.b)) def point2lineDistance(a,b,p): # https://en.wikipedia.org/wiki/Point-line_distance#Line_defined_by_two_points ab=b-a num=abs(ab.y*p.x - ab.x*p.y + b.x*a.y - a.x*b.y) denum=math.sqrt(ab.y**2+ab.x**2) return num/denum # double_area / side_length == height def angleDiff(alpha,beta): diff=abs(alpha-beta) if diff>math.pi: diff=2*math.pi-diff return diff