Changeset - d07ae4bfa145
[Not reviewed]
default
0 3 0
Laman - 6 years ago 2019-03-06 18:03:44

transforming points and lines with a matrix
3 files changed with 40 insertions and 4 deletions:
0 comments (0 inline, 0 general)
exp/geometry.py
Show inline comments
 
@@ -25,12 +25,24 @@ class Line:
 

	
 
	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)
 
@@ -48,12 +60,16 @@ class Line:
 
		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
 

	
exp/tests/test_geometry.py
Show inline comments
 
import math
 
import random
 
from unittest import TestCase
 

	
 
import numpy as np
 

	
 
from geometry import Line,EPoint
 

	
 
random.seed(361)
 

	
 

	
 
class TestLine(TestCase):
 
@@ -86,6 +88,18 @@ class TestLine(TestCase):
 
		self.assertAlmostEqual(p_._d,diag/2)
 

	
 
		q=Line(math.pi*3/4,-diag/2)
 
		q_=q.shiftBasis(newBasis)
 
		self.assertAlmostEqual(q_._alpha,math.pi*7/4)
 
		self.assertAlmostEqual(q_._d,3/2*diag)
 

	
 
	def testTransform(self):
 
		rot90=np.array([[0,-1,0],[1,0,0],[0,0,1]])
 
		p=Line(math.pi/4,10)
 
		p_=p.transform(rot90)
 
		self.assertAlmostEqual(p_.alpha,math.pi*3/4)
 
		self.assertAlmostEqual(p_.d,p.d)
 

	
 
		shiftXY10=np.array([[1,0,10],[0,1,10],[0,0,1]])
 
		p_=p.transform(shiftXY10)
 
		self.assertAlmostEqual(p_.alpha,p.alpha)
 
		self.assertAlmostEqual(p_.d,10+10*math.sqrt(2))
src/analyzer/epoint.py
Show inline comments
 
import math
 

	
 
import numpy as np
 

	
 

	
 
def homogenize(v):
 
	for k in v:
 
	for k in reversed(v):
 
		if k!=0: return v/k
 
	return v
 

	
 

	
 
## Euclidean 2D plane point: (x,y).
 
class EPoint:
 
@@ -18,32 +20,36 @@ class EPoint:
 
	
 
	@property
 
	def y(self): return self._y
 

	
 
	@staticmethod
 
	def fromProjective(point):
 
		if point.item(0)==0: return None
 
		return EPoint(point.item(1)/point.item(0),point.item(2)/point.item(0))
 
		if point.item(2)==0: return None
 
		return EPoint(point.item(0)/point.item(2),point.item(1)/point.item(2))
 

	
 
	@staticmethod
 
	def fromPolar(point,center):
 
		(alpha,length)=point
 
		x=math.cos(alpha)
 
		y=math.sin(alpha)
 
		return length*EPoint(x,y)+center
 

	
 
	def toProjective(self):
 
		return (1,self._x,self._y)
 
		return (self._x,self._y,1)
 

	
 
	def toPolar(self,center):
 
		v=self-center
 
		alpha=math.atan2(v.y,v.x)
 
		if alpha<0: alpha+=2*math.pi
 
		k=self.dist(center)
 
		return (alpha,k)
 

	
 
	def transform(self,matrix):
 
		transformed=np.matmul(matrix,np.array(self.toProjective()).transpose())
 
		return EPoint.fromProjective(transformed)
 

	
 
	def dist(self,a):
 
		return math.sqrt((self._x-a._x)**2+(self._y-a._y)**2)
 

	
 
	def __add__(self,a):
 
		return EPoint(self._x+a._x,self._y+a._y)
 

	
0 comments (0 inline, 0 general)