Correctly find the center for single quadrant arcs
This commit is contained in:
parent
2eac1e427c
commit
af86c5c5a2
2 changed files with 38 additions and 1 deletions
|
|
@ -21,6 +21,7 @@
|
|||
import copy
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
|
|
@ -30,6 +31,7 @@ except(ImportError):
|
|||
from .gerber_statements import *
|
||||
from .primitives import *
|
||||
from .cam import CamFile, FileSettings
|
||||
from .utils import sq_distance
|
||||
|
||||
|
||||
def read(filename):
|
||||
|
|
@ -548,7 +550,7 @@ class GerberParser(object):
|
|||
else:
|
||||
i = 0 if stmt.i is None else stmt.i
|
||||
j = 0 if stmt.j is None else stmt.j
|
||||
center = (start[0] + i, start[1] + j)
|
||||
center = self._find_center(start, end, (i, j))
|
||||
if self.region_mode == 'off':
|
||||
self.primitives.append(Arc(start, end, center, self.direction, self.apertures[self.aperture], quadrant_mode=self.quadrant_mode, level_polarity=self.level_polarity, units=self.settings.units))
|
||||
else:
|
||||
|
|
@ -579,6 +581,35 @@ class GerberParser(object):
|
|||
self.primitives.append(primitive)
|
||||
|
||||
self.x, self.y = x, y
|
||||
|
||||
def _find_center(self, start, end, offsets):
|
||||
"""
|
||||
In single quadrant mode, the offsets are always positive, which means there are 4 possible centers.
|
||||
The correct center is the only one that results in an arc with sweep angle of less than or equal to 90 degrees
|
||||
"""
|
||||
|
||||
if self.quadrant_mode == 'single-quadrant':
|
||||
|
||||
# The Gerber spec says single quadrant only has one possible center, and you can detect
|
||||
# based on the angle. But for real files, this seems to work better - there is usually
|
||||
# only one option that makes sense for the center (since the distance should be the same
|
||||
# from start and end). Find the center that makes the most sense
|
||||
sqdist_diff_min = sys.maxint
|
||||
center = None
|
||||
for factors in [(1, 1), (1, -1), (-1, 1), (-1, -1)]:
|
||||
|
||||
test_center = (start[0] + offsets[0] * factors[0], start[1] + offsets[1] * factors[1])
|
||||
|
||||
sqdist_start = sq_distance(start, test_center)
|
||||
sqdist_end = sq_distance(end, test_center)
|
||||
|
||||
if abs(sqdist_start - sqdist_end) < sqdist_diff_min:
|
||||
center = test_center
|
||||
sqdist_diff_min = abs(sqdist_start - sqdist_end)
|
||||
|
||||
return center
|
||||
else:
|
||||
return (start[0] + offsets[0], start[1] + offsets[1])
|
||||
|
||||
def _evaluate_aperture(self, stmt):
|
||||
self.aperture = stmt.d
|
||||
|
|
|
|||
|
|
@ -297,3 +297,9 @@ def nearly_equal(point1, point2, ndigits = 6):
|
|||
'''Are the points nearly equal'''
|
||||
|
||||
return round(point1[0] - point2[0], ndigits) == 0 and round(point1[1] - point2[1], ndigits) == 0
|
||||
|
||||
def sq_distance(point1, point2):
|
||||
|
||||
diff1 = point1[0] - point2[0]
|
||||
diff2 = point1[1] - point2[1]
|
||||
return diff1 * diff1 + diff2 * diff2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue