@@ -0,0 +1,48 @@
|
||||
import math
|
||||
from app.models.schematic import Point, Bounds
|
||||
|
||||
MAX_COORDINATE = 10_000_000
|
||||
|
||||
def number(p, key, default=0):
|
||||
v = float(p.get(key, default))
|
||||
if not math.isfinite(v) or abs(v) > MAX_COORDINATE:
|
||||
raise ValueError(f'Invalid or excessive numeric property {key}')
|
||||
return v
|
||||
|
||||
def integer(p, key, default=0):
|
||||
return int(number(p, key, default))
|
||||
|
||||
def flag(p, key):
|
||||
return p.get(key, '').upper() in ('T', 'TRUE', '1')
|
||||
|
||||
def coordinate(p, key):
|
||||
# Stored base is 10 mil; fractional field is 1/10000 mil.
|
||||
return number(p, key) + number(p, key + '_FRAC') / 100000
|
||||
|
||||
def point(p, prefix='LOCATION'):
|
||||
return Point(x=coordinate(p, prefix+'.X'), y=-coordinate(p, prefix+'.Y'))
|
||||
|
||||
def transform_point(p: Point, origin: Point, rotation: float, mirrored=False):
|
||||
"""For local generated markers only. SchDoc child geometry is already placed."""
|
||||
x = -p.x if mirrored else p.x
|
||||
a = math.radians(-rotation)
|
||||
return Point(x=origin.x+x*math.cos(a)-p.y*math.sin(a),
|
||||
y=origin.y+x*math.sin(a)+p.y*math.cos(a))
|
||||
|
||||
def bounds(points, padding=0):
|
||||
if not points:
|
||||
return Bounds(x=0,y=0,width=0,height=0)
|
||||
xs,ys = [p.x for p in points],[p.y for p in points]
|
||||
return Bounds(x=min(xs)-padding,y=min(ys)-padding,
|
||||
width=max(xs)-min(xs)+2*padding,height=max(ys)-min(ys)+2*padding)
|
||||
|
||||
def union(boxes):
|
||||
return bounds([p for b in boxes for p in
|
||||
(Point(x=b.x,y=b.y),Point(x=b.x+b.width,y=b.y+b.height))])
|
||||
|
||||
def color(value):
|
||||
n = int(value) & 0xffffff
|
||||
return f'#{n&255:02x}{n>>8&255:02x}{n>>16&255:02x}'
|
||||
|
||||
def poly_path(points, closed=False):
|
||||
return ' '.join(('M' if i==0 else 'L')+f'{p.x:.15g},{p.y:.15g}' for i,p in enumerate(points)) + (' Z' if closed else '')
|
||||
مرجع در شماره جدید
مسدود کردن کاربر