This is the API documentation of LineDream. This was auto generated from the current release.

LineDream

View Source
from .primitives.Line import Line
from .primitives.BaseShape import BaseShape
from .primitives.Ellipse import Circle, Ellipse, Point, Arc
from .primitives.Rectangle import Rectangle, Square
from .enviornment.Canvas import _Canvas
from .helpers.CircleMath import CircleMath
# from .primitives.TextLine import TextLine
# from .enviornment.Tweaks import Tweaks

Canvas = _Canvas
"""
Canvas Singleton Object. This controls the output 'canvas', and rendering of the draw loop.

### Attributes
- width
- height
"""
# Note, I had to do this Canvas=_Canvas thing so these ^ doc strings would work.

__all__ = [
	'Line',
	'Circle',
	'Ellipse',
	'Arc',
	'Point',
	'Rectangle',
	'Square',
	'CircleMath',
	'BaseShape',
	'Canvas',
]
# class Line(LineDream.BaseShape):
View Source
class Line(BaseShape):
	'''This is how you create a line with two or more vertices'''
	def __init__(self, vertices:[Tuple]=None, **kwargs):
		super().__init__(**kwargs)
		if vertices:
			for (x,y) in vertices:
				self.add_vertex(x,y,0)

This is how you create a line with two or more vertices

# Line(vertices: [typing.Tuple] = None, **kwargs)
View Source
	def __init__(self, vertices:[Tuple]=None, **kwargs):
		super().__init__(**kwargs)
		if vertices:
			for (x,y) in vertices:
				self.add_vertex(x,y,0)
# class Circle(LineDream.Ellipse):
View Source
class Circle(Ellipse):
	def __init__(self,x,y, radius, **kwargs):
		super().__init__(x,y, radius, radius, **kwargs)

	def scale(self, percent, _percent_y=0):
		self.radius_x = self.radius_x * percent
		self.radius_y = self.radius_y * percent

This is how to create an ellipse

# Circle(x, y, radius, **kwargs)
View Source
	def __init__(self,x,y, radius, **kwargs):
		super().__init__(x,y, radius, radius, **kwargs)

This is the init for creating an __init__ :param x: x coord of center :param y: y coord of center :param radius_x: radius x :param radius_y: radius y :param kwargs: style kwargs

.. todo:: THIS NEEDS WORK

# def scale(self, percent, _percent_y=0):
View Source
	def scale(self, percent, _percent_y=0):
		self.radius_x = self.radius_x * percent
		self.radius_y = self.radius_y * percent
# class Ellipse(LineDream.BaseShape):
View Source
class Ellipse(BaseShape):
	'''This is how to create an ellipse'''
	def __init__(self,x,y, radius_x, radius_y,   **kwargs):
		'''This is the init for creating an __init__
		:param x: x coord of center
		:param y: y coord of center
		:param radius_x: radius x
		:param radius_y: radius y
		:param kwargs: style kwargs


		.. todo:: THIS NEEDS WORK
		'''
		super().__init__(**kwargs)
		self.x = x
		""" x coord of center"""
		self.y = y
		self.radius_x = radius_x
		self.radius_y = radius_y

		self.is_circle=True

	def add_vertex(self, *coords):
		raise Exception("Ellipses do not have vertexes")

	def transform(self, x=0, y=0, z=0):
		"""
		Send a message to a recipient

		:param str sender: The person sending the message
		:param str recipient: The recipient of the message
		:param str message_body: The body of the message
		:param priority: The priority of the message, can be a number 1-5
		:type priority: integer or None
		:return: the message id
		:rtype: int
		:raises ValueError: if the message_body exceeds 160 characters
		:raises TypeError: if the message_body is not a basestring
		"""

		self.x = self.x + x
		self.y = self.y + y

	def scale(self, percent_x, percent_y=1):
		self.radius_x = self.radius_x * percent_x
		self.radius_y = self.radius_y * percent_y

This is how to create an ellipse

# Ellipse(x, y, radius_x, radius_y, **kwargs)
View Source
	def __init__(self,x,y, radius_x, radius_y,   **kwargs):
		'''This is the init for creating an __init__
		:param x: x coord of center
		:param y: y coord of center
		:param radius_x: radius x
		:param radius_y: radius y
		:param kwargs: style kwargs


		.. todo:: THIS NEEDS WORK
		'''
		super().__init__(**kwargs)
		self.x = x
		""" x coord of center"""
		self.y = y
		self.radius_x = radius_x
		self.radius_y = radius_y

		self.is_circle=True

This is the init for creating an __init__ :param x: x coord of center :param y: y coord of center :param radius_x: radius x :param radius_y: radius y :param kwargs: style kwargs

.. todo:: THIS NEEDS WORK

# x

x coord of center

# def add_vertex(self, *coords):
View Source
	def add_vertex(self, *coords):
		raise Exception("Ellipses do not have vertexes")

Append a set of vertexes to the primitive shape

# def transform(self, x=0, y=0, z=0):
View Source
	def transform(self, x=0, y=0, z=0):
		"""
		Send a message to a recipient

		:param str sender: The person sending the message
		:param str recipient: The recipient of the message
		:param str message_body: The body of the message
		:param priority: The priority of the message, can be a number 1-5
		:type priority: integer or None
		:return: the message id
		:rtype: int
		:raises ValueError: if the message_body exceeds 160 characters
		:raises TypeError: if the message_body is not a basestring
		"""

		self.x = self.x + x
		self.y = self.y + y

Send a message to a recipient

:param str sender: The person sending the message :param str recipient: The recipient of the message :param str message_body: The body of the message :param priority: The priority of the message, can be a number 1-5 :type priority: integer or None :return: the message id :rtype: int :raises ValueError: if the message_body exceeds 160 characters :raises TypeError: if the message_body is not a basestring

# def scale(self, percent_x, percent_y=1):
View Source
	def scale(self, percent_x, percent_y=1):
		self.radius_x = self.radius_x * percent_x
		self.radius_y = self.radius_y * percent_y
# class Arc(LineDream.BaseShape):
View Source
class Arc(BaseShape):
	'''This is how to create an ellipse'''

	def __init__(self, x, y, radius, start_angle, end_angle, **kwargs):
		'''This is the init for creating an __init__
		:param x: x coord of center
		:param y: y coord of center
		:param radius_x: radius x
		:param radius_y: radius y
		:param kwargs: style kwargs


		.. todo:: THIS NEEDS WORK
		'''
		super().__init__(**kwargs)
		self.x = x
		self.y = y
		self.radius = radius
		self.start_angle = start_angle
		self.end_angle = end_angle

		self.is_arc = True

This is how to create an ellipse

# Arc(x, y, radius, start_angle, end_angle, **kwargs)
View Source
	def __init__(self, x, y, radius, start_angle, end_angle, **kwargs):
		'''This is the init for creating an __init__
		:param x: x coord of center
		:param y: y coord of center
		:param radius_x: radius x
		:param radius_y: radius y
		:param kwargs: style kwargs


		.. todo:: THIS NEEDS WORK
		'''
		super().__init__(**kwargs)
		self.x = x
		self.y = y
		self.radius = radius
		self.start_angle = start_angle
		self.end_angle = end_angle

		self.is_arc = True

This is the init for creating an __init__ :param x: x coord of center :param y: y coord of center :param radius_x: radius x :param radius_y: radius y :param kwargs: style kwargs

.. todo:: THIS NEEDS WORK

# class Point(LineDream.Circle):
View Source
class Point(Circle):
	def __init__(self,x,y, **kwargs):
		super().__init__(x,y, .5, **kwargs)

	def scale(self, percent_x=1, _percent_y=1):
		raise Exception('Cannot scale a Point')

This is how to create an ellipse

# Point(x, y, **kwargs)
View Source
	def __init__(self,x,y, **kwargs):
		super().__init__(x,y, .5, **kwargs)

This is the init for creating an __init__ :param x: x coord of center :param y: y coord of center :param radius_x: radius x :param radius_y: radius y :param kwargs: style kwargs

.. todo:: THIS NEEDS WORK

# def scale(self, percent_x=1, _percent_y=1):
View Source
	def scale(self, percent_x=1, _percent_y=1):
		raise Exception('Cannot scale a Point')
# class Rectangle(LineDream.BaseShape):
View Source
class Rectangle(BaseShape):
	def __init__(self, c_x, c_y, width, height, **kwargs):
		"""
		Creates a Rectangle Primitive

		Parameters
		----------
		c_x : int
			center of rectangle x coord

		c_y: int
			center of rectangle y coord

		:param width:
		:param height:
		:param kwargs:
		"""

		super().__init__(**kwargs)
		self.c_x = c_x
		self.c_y = c_y
		self.width = width
		self.height = height

		self.close_path = True

		# top left
		t_l_x = c_x - (width/2)
		t_l_y = c_y - (height/2)

		# top right
		t_r_x = c_x + (width/2)
		t_r_y = c_y - (height/2)

		# bottom right
		b_r_x = c_x + (width / 2)
		b_r_y = c_y + (height / 2)

		# bottom left
		b_l_x = c_x - (width/2)
		b_l_y = c_y + (height/2)

		# this order is very important.
		# It adds the vertex's in a clockwise rotation
		self.add_vertex(t_l_x, t_l_y)
		self.add_vertex(t_r_x, t_r_y)
		self.add_vertex(b_r_x, b_r_y)
		self.add_vertex(b_l_x, b_l_y)

All provided primatives inherit from this class. If a user wants to make thier own primative, its reccomended to inherit from this class so the new primative is added to the draw queue.

# Rectangle(c_x, c_y, width, height, **kwargs)
View Source
	def __init__(self, c_x, c_y, width, height, **kwargs):
		"""
		Creates a Rectangle Primitive

		Parameters
		----------
		c_x : int
			center of rectangle x coord

		c_y: int
			center of rectangle y coord

		:param width:
		:param height:
		:param kwargs:
		"""

		super().__init__(**kwargs)
		self.c_x = c_x
		self.c_y = c_y
		self.width = width
		self.height = height

		self.close_path = True

		# top left
		t_l_x = c_x - (width/2)
		t_l_y = c_y - (height/2)

		# top right
		t_r_x = c_x + (width/2)
		t_r_y = c_y - (height/2)

		# bottom right
		b_r_x = c_x + (width / 2)
		b_r_y = c_y + (height / 2)

		# bottom left
		b_l_x = c_x - (width/2)
		b_l_y = c_y + (height/2)

		# this order is very important.
		# It adds the vertex's in a clockwise rotation
		self.add_vertex(t_l_x, t_l_y)
		self.add_vertex(t_r_x, t_r_y)
		self.add_vertex(b_r_x, b_r_y)
		self.add_vertex(b_l_x, b_l_y)

Creates a Rectangle Primitive

Parameters
  • c_x (int): center of rectangle x coord
  • c_y (int): center of rectangle y coord
  • :param width:
  • :param height:
  • :param kwargs:
# class Square(LineDream.Rectangle):
View Source
class Square(Rectangle):
	def __init__(self, c_x: int, c_y: int, width, **kwargs):
		"""
		Create a square primitive

		:param c_x: center of square x coordinate
		:param c_y: center of square y coordinate
		:param width: height/width of the square.
		:param kwargs: style dict
		"""

		super().__init__(c_x, c_y, width, width, **kwargs)

All provided primatives inherit from this class. If a user wants to make thier own primative, its reccomended to inherit from this class so the new primative is added to the draw queue.

# Square(c_x: int, c_y: int, width, **kwargs)
View Source
	def __init__(self, c_x: int, c_y: int, width, **kwargs):
		"""
		Create a square primitive

		:param c_x: center of square x coordinate
		:param c_y: center of square y coordinate
		:param width: height/width of the square.
		:param kwargs: style dict
		"""

		super().__init__(c_x, c_y, width, width, **kwargs)

Create a square primitive

:param c_x: center of square x coordinate :param c_y: center of square y coordinate :param width: height/width of the square. :param kwargs: style dict

# class CircleMath:
View Source
class CircleMath:
	'''
	A class with helper methods for circles
	'''

	@staticmethod
	def distance_to_coords(degrees, distance):
		angle_radians = degrees * math.pi / 180
		x = math.cos(angle_radians) * distance
		y = math.sin(angle_radians) * distance
		return x, y

	@staticmethod
	def rotate(p, origin=(0, 0), degrees=0):
		# https://stackoverflow.com/a/58781388/6775715
		angle = np.deg2rad(degrees)
		R = np.array([[np.cos(angle), -np.sin(angle)],
					  [np.sin(angle), np.cos(angle)]])
		o = np.atleast_2d(origin)
		p = np.atleast_2d(p)
		rv = np.squeeze((R @ (p.T - o.T) + o.T).T)
		#todo: remove this once native numpy arrays are supported
		return rv.tolist()

	@staticmethod
	def degrees_to_radians(degrees):
		return (math.radians(degrees / math.pi))

A class with helper methods for circles

# CircleMath()
#
@staticmethod
def distance_to_coords(degrees, distance):
View Source
	@staticmethod
	def distance_to_coords(degrees, distance):
		angle_radians = degrees * math.pi / 180
		x = math.cos(angle_radians) * distance
		y = math.sin(angle_radians) * distance
		return x, y
#
@staticmethod
def rotate(p, origin=(0, 0), degrees=0):
View Source
	@staticmethod
	def rotate(p, origin=(0, 0), degrees=0):
		# https://stackoverflow.com/a/58781388/6775715
		angle = np.deg2rad(degrees)
		R = np.array([[np.cos(angle), -np.sin(angle)],
					  [np.sin(angle), np.cos(angle)]])
		o = np.atleast_2d(origin)
		p = np.atleast_2d(p)
		rv = np.squeeze((R @ (p.T - o.T) + o.T).T)
		#todo: remove this once native numpy arrays are supported
		return rv.tolist()
#
@staticmethod
def degrees_to_radians(degrees):
View Source
	@staticmethod
	def degrees_to_radians(degrees):
		return (math.radians(degrees / math.pi))
# class BaseShape:
View Source
class BaseShape(object):
	'''All provided primatives inherit from this class. If a user wants to make thier own primative, its reccomended to
	inherit from this class so the new primative is added to the draw queue.'''
	def __init__(self, **kwargs):
		self._vertices = np.array([])
		self._fill_color='none'
		self._stroke_color='black'
		self._stroke_width=1
		self._close_path = False
		self._fill_opacity = 1.0

		self.is_circle=False
		self.is_arc=False
		self.is_multipath = False

		for k,v in kwargs.items():
			if hasattr(self, k):
				setattr(self, k, v)
			else:
				sys.stderr.write(f'attr "{k}" does not exist.')
				# print(f'attr "{k}" does not exist.')

		_Canvas.draw_queue.append(self)


	def __str__(self):
		return f'<{__class__} fill_color: {self.fill_color}>'

	def __repr__(self):
		return f'<{__class__} fill_color: {self.fill_color}>'

	@property
	def fill_color(self):
		'''The fill color of the shape'''
		return self._fill_color

	@fill_color.setter
	def fill_color(self, v):
		self._fill_color = v


	@property
	def fill_opacity(self):
		'''The fill opacity of the shape'''
		return self._fill_opacity

	@fill_opacity.setter
	def fill_opacity(self, v):
		self._fill_opacity = v

	@property
	def close_path(self):
		'''Upon rendering the shape, the last vertex will connect to the first vertex'''
		return self._close_path

	@close_path.setter
	def close_path(self, v:bool):
		self._close_path = v

	@property
	def stroke_color(self):
		'''The stroke color of the shape'''
		return self._stroke_color

	@stroke_color.setter
	def stroke_color(self, v):
		self._stroke_color = v

	@property
	def stroke_width(self):
		'''The stroke width of the shape'''
		return self._stroke_width

	@stroke_width.setter
	def stroke_width(self, v):
		self._stroke_width = v

	@property
	def vertices(self):
		'''The list of vertices'''
		return self._vertices

	@property
	def first_vertex(self):
		'''The first vertex of the shape'''
		# or do you just raise an exception?
		rv = (None, None)
		if  self.vertices.size > 0:
			_rv = self.vertices[0]
			rv = (_rv[0], _rv[1])

		return rv

	# Not sure why this was here, but it was not used so I'm commenting out.
	# @property
	# def last_vertex(self):
	# 	# or do you just raise an exception?
	# 	rv = (None, None)
	# 	if  self.vertices.size > 0:
	# 		_rv = self.vertices[-1]
	# 		rv = (_rv[0], _rv[1])
	#
	# 	return rv

	# @property
	# def length(self):
	# 	x = np.array(xcoordinates)
	# 	y = np.array(ycoordinates)
	#
	# 	dist_array = (x[:-1] - x[1:]) ** 2 + (y[:-1] - y[1:]) ** 2
	#
	# 	np.sum(np.sqrt(dist_array))

	@property
	def min_x(self):
		'''The smallest x value of all the vertices'''
		rv = self.first_vertex[0]

		_v = self.vertices.tolist()

		for x,y, z, _ in _v:
			if x < rv:
				rv = x
		return rv

	@property
	def max_x(self):
		'''The largest x value of all the vertices'''
		rv = self.first_vertex[0]

		_v = self.vertices.tolist()

		for x,y, z, _ in _v:
			if x > rv:
				rv = x
		return rv

	@property
	def min_y(self):
		'''The smallest y value of all the vertices'''
		rv = self.first_vertex[1]

		_v = self.vertices.tolist()

		for x,y, z, _ in _v:
			if y < rv:
				rv = y
		return rv

	@property
	def max_y(self):
		'''The largest y value of all the vertices'''
		rv = self.first_vertex[1]

		_v = self.vertices.tolist()

		for x,y, z, _ in _v:
			if y > rv:
				rv = y
		return rv

	@property
	def center(self):
		'''The center of the shape based on the min/max x/y'''
		x = ((self.max_x - self.min_x)/2) + self.min_x
		y = ((self.max_y - self.min_y)/2) + self.min_y
		return (x,y)

	# def rotate(self, degrees, origin=None):
	#
	# 	if not origin:
	# 		x = [p[0] for p in self.vertices]
	# 		y = [p[1] for p in self.vertices]
	# 		origin = (max(x) + min(x)) / 2, (max(y) + min(y)) / 2
	#
	# 	self._vertices = CircleMath.rotate(self.vertices, origin=origin, degrees=degrees)

	def add_vertex(self, x, y, z=0):
		'''Append a set of vertexes to the primitive shape'''

		l = self._vertices.tolist()
		l.append([x,y,z,1])

		self._vertices = np.array(l)


	def transform(self, x, y, z=0):
		'''Transform the vertices based on x/y coords'''

		# THIS IS DEFAULT BEHAVIOR IF IT IS NOT OVERRIDEN IN THE DERIVED CLASS.
		# This will work for shapes/objects that user vertex's.. but not for things like Circles
		#
		# for idx, (o_x,o_y) in enumerate(self._vertices):
		# 	o_x = o_x + x
		# 	o_y = o_y + y
		#
		# 	self._vertices[idx] = (o_x, o_y)

		# tmat = matrix.translation_matrix(x, y, z)

		translate_matrix = np.identity(4)
		translate_matrix[0, -1] = x
		translate_matrix[1, -1] = y
		translate_matrix[2, -1] = z


		self._vertices = np.dot(self._vertices, translate_matrix.T)[:, :4]


	def rotate(self, theta, origin=None, axis=np.array([0, 0, 1])):
		"""Rotate the display by the given angle along the given axis.

		:param theta: The angle by which to rotate (in radians)
		:type theta: float

		:param axis: The axis along which to rotate (defaults to the z-axis)
		:type axis: np.ndarray or list

	   """

		#CONVERT DEGREES TO RADIANS
		theta = theta * math.pi / 180

		axis = np.array(axis[:])

		#

		# tmat = matrix.rotation_matrix(axis, theta)

		#

		# NOTE: THIS ALL MIGHT NEED TO BE RADIANS
		# This might be the wrong interpretatino...
		x = axis[0]
		y = axis[1]
		z = axis[2]

		# x, y, z = _normalize(axis)

		s = np.sin(theta)
		c = np.cos(theta)
		c1 = 1 - c

		rotation = np.identity(4)

		rotation[0, 0] = x * x * c1 + c
		rotation[0, 1] = x * y * c1 - z * s
		rotation[0, 2] = x * z * c1 + y * s
		rotation[1, 0] = y * x * c1 + z * s
		rotation[1, 1] = y * y * c1 + c
		rotation[1, 2] = y * z * c1 - x * s
		rotation[2, 0] = x * z * c1 - y * s
		rotation[2, 1] = y * z * c1 + x * s
		rotation[2, 2] = z * z * c1 + c

		if origin == None:
			x_c,y_c = self.center
		else:
			x_c = origin[0]
			y_c = origin[1]

		self.transform(-x_c, -y_c)


		rotation[0, -1] = x_c
		rotation[1, -1] = y_c
		rotation[2, -1] = 1

		self._vertices = np.dot(self._vertices, rotation.T)[:, :4]

		# self.transform(x_c, y_c)
		# self._vertices = self._vertices.dot(rotation)


	def rotate_x(self, theta):
		"""Rotate the view along the x axis.

		:param theta: angle by which to rotate (in radians)
		:type theta: float

		:returns: The rotation matrix used to apply the transformation.
		:rtype: np.ndarray

		"""
		self.rotate(theta, axis=np.array([1, 0, 0]))

	def rotate_y(self, theta):
		"""Rotate the view along the y axis.

		:param theta: angle by which to rotate (in radians)
		:type theta: float

		:returns: The rotation matrix used to apply the transformation.
		:rtype: np.ndarray

	   """
		self.rotate(theta, axis=np.array([0, 1, 0]))

	def rotate_z(self, theta):
		"""Rotate the view along the z axis.

		:param theta: angle by which to rotate (in radians)
		:type theta: float

		:returns: The rotation matrix used to apply the transformation.
		:rtype: np.ndarray

	   """
		self.rotate(theta, axis=np.array([0, 0, 1]))


	def scale(self, amt, amt_y=None, origin=None):

		sys.stderr.write("Scale is not fully implemented yet.\n")

		if amt_y==None:
			amt_y = amt

		scale_matrix = np.identity(4)
		scale_matrix[0, 0] = amt
		scale_matrix[1, 1] = amt_y
		scale_matrix[2, 2] = 1 # default for z

		self._vertices = self._vertices.dot(scale_matrix)

All provided primatives inherit from this class. If a user wants to make thier own primative, its reccomended to inherit from this class so the new primative is added to the draw queue.

# BaseShape(**kwargs)
View Source
	def __init__(self, **kwargs):
		self._vertices = np.array([])
		self._fill_color='none'
		self._stroke_color='black'
		self._stroke_width=1
		self._close_path = False
		self._fill_opacity = 1.0

		self.is_circle=False
		self.is_arc=False
		self.is_multipath = False

		for k,v in kwargs.items():
			if hasattr(self, k):
				setattr(self, k, v)
			else:
				sys.stderr.write(f'attr "{k}" does not exist.')
				# print(f'attr "{k}" does not exist.')

		_Canvas.draw_queue.append(self)
# fill_color

The fill color of the shape

# fill_opacity

The fill opacity of the shape

# close_path

Upon rendering the shape, the last vertex will connect to the first vertex

# stroke_color

The stroke color of the shape

# stroke_width

The stroke width of the shape

# vertices

The list of vertices

# first_vertex

The first vertex of the shape

# min_x

The smallest x value of all the vertices

# max_x

The largest x value of all the vertices

# min_y

The smallest y value of all the vertices

# max_y

The largest y value of all the vertices

# center

The center of the shape based on the min/max x/y

# def add_vertex(self, x, y, z=0):
View Source
	def add_vertex(self, x, y, z=0):
		'''Append a set of vertexes to the primitive shape'''

		l = self._vertices.tolist()
		l.append([x,y,z,1])

		self._vertices = np.array(l)

Append a set of vertexes to the primitive shape

# def transform(self, x, y, z=0):
View Source
	def transform(self, x, y, z=0):
		'''Transform the vertices based on x/y coords'''

		# THIS IS DEFAULT BEHAVIOR IF IT IS NOT OVERRIDEN IN THE DERIVED CLASS.
		# This will work for shapes/objects that user vertex's.. but not for things like Circles
		#
		# for idx, (o_x,o_y) in enumerate(self._vertices):
		# 	o_x = o_x + x
		# 	o_y = o_y + y
		#
		# 	self._vertices[idx] = (o_x, o_y)

		# tmat = matrix.translation_matrix(x, y, z)

		translate_matrix = np.identity(4)
		translate_matrix[0, -1] = x
		translate_matrix[1, -1] = y
		translate_matrix[2, -1] = z


		self._vertices = np.dot(self._vertices, translate_matrix.T)[:, :4]

Transform the vertices based on x/y coords

# def rotate(self, theta, origin=None, axis=array([0, 0, 1])):
View Source
	def rotate(self, theta, origin=None, axis=np.array([0, 0, 1])):
		"""Rotate the display by the given angle along the given axis.

		:param theta: The angle by which to rotate (in radians)
		:type theta: float

		:param axis: The axis along which to rotate (defaults to the z-axis)
		:type axis: np.ndarray or list

	   """

		#CONVERT DEGREES TO RADIANS
		theta = theta * math.pi / 180

		axis = np.array(axis[:])

		#

		# tmat = matrix.rotation_matrix(axis, theta)

		#

		# NOTE: THIS ALL MIGHT NEED TO BE RADIANS
		# This might be the wrong interpretatino...
		x = axis[0]
		y = axis[1]
		z = axis[2]

		# x, y, z = _normalize(axis)

		s = np.sin(theta)
		c = np.cos(theta)
		c1 = 1 - c

		rotation = np.identity(4)

		rotation[0, 0] = x * x * c1 + c
		rotation[0, 1] = x * y * c1 - z * s
		rotation[0, 2] = x * z * c1 + y * s
		rotation[1, 0] = y * x * c1 + z * s
		rotation[1, 1] = y * y * c1 + c
		rotation[1, 2] = y * z * c1 - x * s
		rotation[2, 0] = x * z * c1 - y * s
		rotation[2, 1] = y * z * c1 + x * s
		rotation[2, 2] = z * z * c1 + c

		if origin == None:
			x_c,y_c = self.center
		else:
			x_c = origin[0]
			y_c = origin[1]

		self.transform(-x_c, -y_c)


		rotation[0, -1] = x_c
		rotation[1, -1] = y_c
		rotation[2, -1] = 1

		self._vertices = np.dot(self._vertices, rotation.T)[:, :4]

Rotate the display by the given angle along the given axis.

:param theta: The angle by which to rotate (in radians) :type theta: float

:param axis: The axis along which to rotate (defaults to the z-axis) :type axis: np.ndarray or list

# def rotate_x(self, theta):
View Source
	def rotate_x(self, theta):
		"""Rotate the view along the x axis.

		:param theta: angle by which to rotate (in radians)
		:type theta: float

		:returns: The rotation matrix used to apply the transformation.
		:rtype: np.ndarray

		"""
		self.rotate(theta, axis=np.array([1, 0, 0]))

Rotate the view along the x axis.

:param theta: angle by which to rotate (in radians) :type theta: float

:returns: The rotation matrix used to apply the transformation. :rtype: np.ndarray

# def rotate_y(self, theta):
View Source
	def rotate_y(self, theta):
		"""Rotate the view along the y axis.

		:param theta: angle by which to rotate (in radians)
		:type theta: float

		:returns: The rotation matrix used to apply the transformation.
		:rtype: np.ndarray

	   """
		self.rotate(theta, axis=np.array([0, 1, 0]))

Rotate the view along the y axis.

:param theta: angle by which to rotate (in radians) :type theta: float

:returns: The rotation matrix used to apply the transformation. :rtype: np.ndarray

# def rotate_z(self, theta):
View Source
	def rotate_z(self, theta):
		"""Rotate the view along the z axis.

		:param theta: angle by which to rotate (in radians)
		:type theta: float

		:returns: The rotation matrix used to apply the transformation.
		:rtype: np.ndarray

	   """
		self.rotate(theta, axis=np.array([0, 0, 1]))

Rotate the view along the z axis.

:param theta: angle by which to rotate (in radians) :type theta: float

:returns: The rotation matrix used to apply the transformation. :rtype: np.ndarray

# def scale(self, amt, amt_y=None, origin=None):
View Source
	def scale(self, amt, amt_y=None, origin=None):

		sys.stderr.write("Scale is not fully implemented yet.\n")

		if amt_y==None:
			amt_y = amt

		scale_matrix = np.identity(4)
		scale_matrix[0, 0] = amt
		scale_matrix[1, 1] = amt_y
		scale_matrix[2, 2] = 1 # default for z

		self._vertices = self._vertices.dot(scale_matrix)

Canvas Singleton Object. This controls the output 'canvas', and rendering of the draw loop.

Attributes

  • width
  • height