Files @ 29f28718a69b
Branch filter:

Location: OneEye/exp/geometry.py - annotation

Laman
transitional data processing
import math

from analyzer.epoint import EPoint


class Line:
	def __init__(self,alpha,d):
		self._alpha=alpha
		self._d=d
		self._sin=math.sin(alpha)
		self._cos=math.cos(alpha)

	@staticmethod
	def fromNormal(a,b,c):
		"""ax + by + c = 0"""
		sign=-c/abs(c) if c!=0 else 1
		norm=sign*math.sqrt(a**2+b**2)
		(a_,b_,c_)=(a/norm,b/norm,c/norm)
		alpha=math.acos(a_) if b_>=0 else 2*math.pi-math.acos(a_)
		return Line(alpha,-c_)

	@staticmethod
	def fromPoints(a,b):
		return Line.fromNormal(a.y-b.y, b.x-a.x, (b.y-a.y)*a.x+(a.x-b.x)*a.y)

	def toNormal(self):
		# https://en.wikipedia.org/wiki/Line_(mathematics)#In_normal_form
		"""ax + by + c = 0"""
		return (self._cos, self._sin, -self._d)

	def toPoints(self):
		(a,b,c)=self.toNormal()
		assert a!=0 or b!=0
		if a==0:
			y=-c/b
			return (EPoint(0,y),EPoint(10,y))
		elif b==0:
			x=-c/a
			return (EPoint(x,0),EPoint(x,10))
		else:
			return (EPoint(0,-c/b),EPoint(-c/a,0))

	def intersect(self,line):
		if self._alpha==line._alpha: return None
		(a,b,c)=self.toNormal()
		(d,e,f)=line.toNormal()
		x=(b*f-c*e)/(a*e-b*d)
		y=(c*d-a*f)/(a*e-b*d)
		return EPoint(x,y)

	def distanceTo(self,point):
		# https://en.wikipedia.org/wiki/Point-line_distance#Line_defined_by_an_equation
		(a,b,c)=self.toNormal()
		return abs(a*point.x+b*point.y+c) # a**2 + b**2 == 1 for Hesse normal form

	def shiftBasis(self,newBasis):
		(a,b,c)=self.toNormal()
		if a!=0:
			point=EPoint(-c/a,0)
		else:
			point=EPoint(0,-c/b)
		(x_,y_)=point-newBasis
		c_=-a*x_-b*y_
		return Line.fromNormal(a,b,c_)

	def transform(self,matrix):
		transformed=(p.transform(matrix) for p in self.toPoints())
		return Line.fromPoints(*transformed)

	@property
	def alpha(self): return self._alpha

	@property
	def d(self): return self._d

	def __str__(self): return "Line({0},{1})".format(round(self._alpha,3),round(self._d))
	def __repr__(self): return "Line({0},{1})".format(self._alpha,self._d)


def angleDiff(alpha,beta):
	diff=abs(alpha-beta)
	if diff>math.pi: diff=2*math.pi-diff
	return diff