Source code for openglider.plots.marks

import math
import numpy

from openglider.vector.functions import rotation_2d
from openglider.vector.polyline import PolyLine2D

default_scale = 0.8


[docs]class Polygon(object): def __init__(self, edges=3, scale=default_scale, name=None): self.scale = scale self.num_edges = edges self.name = name def __json__(self): return {"scale": self.scale, "edges": self.num_edges} def __call__(self, p1, p2): center = (p1+p2)/2 diff = (p2-center) * self.scale points = [center + rotation_2d(math.pi*2*i/self.num_edges).dot(diff) for i in range(self.num_edges+1)] return [PolyLine2D(points, name=self.name)]
[docs]class Triangle(Polygon): def __init__(self, scale=default_scale): super(Triangle, self).__init__(3, scale) def __json__(self): return {"scale": self.scale}
[docs]class Arrow(object): def __init__(self, left=True, scale=default_scale, name=None): self.left = left self.scale = scale self.name = name def __json__(self): return { "left": self.left, "scale": self.scale } def __call__(self, p1, p2): d = (p2 - p1)*self.scale dr = numpy.array([-d[1], d[0]])/math.sqrt(2) if not self.left: dr = -dr return [PolyLine2D([p1, p1+d, p1+d/2+dr, p1], name=self.name)]
[docs]class Line(object): def __init__(self, rotation=0, offset=0, name=None): self.rotation = rotation self.offset = offset self.name = name def __json__(self): return { "rotation": self.rotation, "offset": self.offset, "name": self.name } def __call__(self, p1, p2): if self.rotation: center = (p1+p2)/2 rot = rotation_2d(self.rotation) return [PolyLine2D([center + rot.dot(p1-center), center+rot.dot(p2-center)], name=self.name)] else: return [PolyLine2D([p1, p2], name=self.name)]
[docs]class Cross(Line): def __call__(self, p1, p2): l1 = Line(rotation=self.rotation) l2 = Line(rotation=self.rotation+math.pi/2) return l1(p1, p2) + l2(p1, p2)
[docs]class Dot(object): def __init__(self, *positions): self.positions = positions def __json__(self): return {"pos": self.positions} def __call__(self, p1, p2): dots = [] for x in self.positions: p = p1 + x * (p2 - p1) dots.append(p) return [PolyLine2D([p]) for p in dots]
class _Modify(object): def __init__(self, func): self.func = func def __json__(self): return {"func": self.func} def __repr__(self): return "{}->{}".format(self.__class__.__name__, repr(self.func)) def __call__(self, p1, p2, *args, **kwargs): return self.func(p1, p2, *args, **kwargs)
[docs]class Rotate(_Modify): def __init__(self, func, rotation, center=True): self.angle = rotation self.rotation = rotation_2d(rotation) super(Rotate, self).__init__(func) def __json__(self): return {"func": self.func, "rotation": self.angle} def __repr__(self): return "Rotate({})->{}".format(self.angle, self.func) def __call__(self, p1, p2): diff = (p2 - p1)/2 center = (p1 + p2)/2 diff_new = self.rotation.dot(diff) p1_new, p2_new = center + diff_new, center - diff_new return super(Rotate, self).__call__(p1_new, p2_new)
[docs]class OnLine(_Modify): """ Modify Mark to sit centered on p2 rather than in between |x| <- old | | | x <- new | | """ def __call__(self, p1, p2, *args, **kwargs): p1_2 = 0.5 * (p1+p2) p2_2 = 1.5 * p1 - 0.5 * p2 return super(OnLine, self).__call__(p1_2, p2_2, *args, **kwargs)
[docs]class Inside(_Modify): """ Modify Mark to be on the other side (inside) |x| <- old | | | |x <- new l1| | l2 """ def __call__(self, p1, p2, *args, **kwargs): p1_2 = 2*p1-p2 p2_2 = p1 return super(Inside, self).__call__(p1_2, p2_2, *args, **kwargs)