convex_hull for faster rotate_and_scale_to_fit
This commit is contained in:
parent
3b35f93223
commit
38c71e1fe5
|
@ -2,7 +2,8 @@ from __future__ import division
|
|||
|
||||
from math import sin, cos, radians
|
||||
|
||||
from .paths import simplify_paths, sort_paths, join_paths, crop_paths
|
||||
from .paths import (
|
||||
simplify_paths, sort_paths, join_paths, crop_paths, convex_hull)
|
||||
|
||||
try:
|
||||
import cairo
|
||||
|
@ -61,10 +62,18 @@ class Drawing(object):
|
|||
with open(filename, 'w') as fp:
|
||||
fp.write(self.dumps_svg())
|
||||
|
||||
@property
|
||||
def points(self):
|
||||
return [(x, y) for path in self.paths for x, y in path]
|
||||
|
||||
@property
|
||||
def convex_hull(self):
|
||||
return convex_hull(self.points)
|
||||
|
||||
@property
|
||||
def bounds(self):
|
||||
if not self._bounds:
|
||||
points = [(x, y) for path in self.paths for x, y in path]
|
||||
points = self.points
|
||||
if points:
|
||||
x1 = min(x for x, y in points)
|
||||
x2 = max(x for x, y in points)
|
||||
|
@ -168,16 +177,18 @@ class Drawing(object):
|
|||
scale = min(width / self.width, height / self.height)
|
||||
return self.scale(scale, scale).center(width, height)
|
||||
|
||||
def rotate_and_scale_to_fit(self, width, height, padding=0, step=5):
|
||||
drawings = []
|
||||
def rotate_and_scale_to_fit(self, width, height, padding=0, step=1):
|
||||
values = []
|
||||
width -= padding * 2
|
||||
height -= padding * 2
|
||||
hull = Drawing([self.convex_hull])
|
||||
for angle in range(0, 180, step):
|
||||
drawing = self.rotate(angle)
|
||||
scale = min(width / drawing.width, height / drawing.height)
|
||||
drawings.append((scale, angle, drawing))
|
||||
scale, angle, drawing = max(drawings)
|
||||
return drawing.scale(scale, scale).center(width, height)
|
||||
d = hull.rotate(angle)
|
||||
scale = min(width / d.width, height / d.height)
|
||||
print angle, d.width, d.height
|
||||
values.append((scale, angle))
|
||||
scale, angle = max(values)
|
||||
return self.rotate(angle).scale(scale, scale).center(width, height)
|
||||
|
||||
def remove_paths_outside(self, width, height):
|
||||
e = 1e-8
|
||||
|
@ -192,11 +203,13 @@ class Drawing(object):
|
|||
paths.append(path)
|
||||
return Drawing(paths)
|
||||
|
||||
def render(self, scale=109, margin=1, line_width=0.5/25.4, show_bounds=True):
|
||||
def render(self, scale=109, margin=1, line_width=0.5/25.4,
|
||||
use_axi_bounds=True, show_axi_bounds=True):
|
||||
if cairo is None:
|
||||
raise Exception('Drawing.render() requires cairo')
|
||||
# x1, y1, x2, y2 = self.bounds
|
||||
x1, y1, x2, y2 = (0, 0, 12, 8.5)
|
||||
x1, y1, x2, y2 = self.bounds
|
||||
if use_axi_bounds:
|
||||
x1, y1, x2, y2 = (0, 0, 12, 8.5)
|
||||
w = x2 - x1
|
||||
h = y2 - y1
|
||||
margin *= scale
|
||||
|
@ -211,7 +224,7 @@ class Drawing(object):
|
|||
dc.translate(-x1, -y1)
|
||||
dc.set_source_rgb(1, 1, 1)
|
||||
dc.paint()
|
||||
if show_bounds:
|
||||
if show_axi_bounds:
|
||||
dc.set_source_rgb(0.5, 0.5, 0.5)
|
||||
dc.set_line_width(1 / scale)
|
||||
dc.rectangle(0, 0, 12, 8.5)
|
||||
|
|
14
axi/paths.py
14
axi/paths.py
|
@ -1,5 +1,5 @@
|
|||
from math import hypot
|
||||
from shapely.geometry import LineString
|
||||
from shapely import geometry
|
||||
|
||||
from .spatial import Index
|
||||
|
||||
|
@ -17,7 +17,7 @@ def load_paths(filename):
|
|||
def simplify_path(points, tolerance):
|
||||
if len(points) < 2:
|
||||
return points
|
||||
line = LineString(points)
|
||||
line = geometry.LineString(points)
|
||||
line = line.simplify(tolerance, preserve_topology=False)
|
||||
return list(line.coords)
|
||||
|
||||
|
@ -109,3 +109,13 @@ def crop_paths(paths, x1, y1, x2, y2):
|
|||
for path in paths:
|
||||
result.extend(crop_path(path, x1, y1, x2, y2))
|
||||
return result
|
||||
|
||||
def convex_hull(points):
|
||||
hull = geometry.MultiPoint(points).convex_hull
|
||||
if isinstance(hull, geometry.Polygon):
|
||||
return list(hull.exterior.coords)
|
||||
if isinstance(hull, geometry.LineString):
|
||||
return list(hull.coords)
|
||||
if isinstance(hull, geometry.Point):
|
||||
return list(hull.coords)
|
||||
raise Exception('unhandled convex hull geometry')
|
||||
|
|
|
@ -84,15 +84,16 @@ def main():
|
|||
ds = []
|
||||
for filename, angle in zip(filenames, angles):
|
||||
ds.append(axi.Drawing(axi.load_paths(filename)).scale_to_fit(8.5, 12).scale(1, -1))
|
||||
d = grid_drawings(ds, 2, 1)
|
||||
# d = grid_drawings(ds, 2, 1)
|
||||
d = ds[0]
|
||||
print len(d.paths)
|
||||
print 'joining paths'
|
||||
d = d.join_paths(0.01)
|
||||
print len(d.paths)
|
||||
print 'transforming paths'
|
||||
# d = d.scale(1, -1)
|
||||
d = d.rotate_and_scale_to_fit(8.5, 12 - text.height - 0.75, step=5)
|
||||
d = d.origin()
|
||||
d = d.rotate_and_scale_to_fit(8.5, 12 - text.height - 0.75)
|
||||
# d = d.origin()
|
||||
print 'sorting paths'
|
||||
d = d.sort_paths()
|
||||
print 'joining paths'
|
||||
|
|
Loading…
Reference in New Issue