Skip to content
This repository has been archived by the owner on Oct 7, 2020. It is now read-only.

Support generating two-terminal footprints with IPC density argument #439

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 4 additions & 58 deletions AUTHORS.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
**Maintainer:**

* Thomas Pointhuber <[email protected]> @pointhi
* Rene Pöschl, @poeschlr
* @evanshultz


**Contributors:**

People who have submitted patches, reported bugs, consulted features or generally made KicadModTree better

* Oliver, @SchrodingersGat
* Jan W. Krieger, @jkriege2
* Rene Pöschl, @poeschlr
* Frank, @Frankkkkk
* @Hackscribble
* @stoth
* Patrick Pelletier, @ppelleti
* @DASFrank
* Dominik Baack, @matyro
* Jordi Pakey-Rodriguez, @0xdec
* Jordi Orlando, @0xdec
* @evanshultz
* George, @grob6000
* Tobias Müller, @twam
* Terje Io, @terjeio
Expand All @@ -26,58 +27,3 @@ People who have submitted patches, reported bugs, consulted features or generall
* Trevor Vannoy, @tvannoy
* Kari Hautio, @kh4
* Stefan, @Misca1234
* Antonio Vazquez, @antoniovazquezblanco
* Hendrik v. Raven, @lorem-ipsum
* Asuki Kono, @asukiaaa
* Xathar, @jneiva08
* @matthuszagh
* @ferdymercury
* @jhalmen
* @herostrat
* @fauxpark
* @matthijskooijman
* Clara Hobbs, @Ratfink
* @MRQ
* Stefan Krüger, @s-light
* John Whitmore, @johnfwhitmore
* Daniel Mack, @zonque
* @dominformant
* @tpambor
* @nivekg
* Joel, @myfreescalewebpage
* JonRB, @eeyrjmr
* Alexander Ransmann, @cronJ
* Christian Schlüter, @chschlue
* Chase Patterson, @chapatt
* Rolf Schäuble, @rschaeuble
* @penoud
* @ki5libs
* @fvollmer
* @cp-aquila
* Anders Wallin, @aewallin
* Jonas Schievink, @jonas-schievink
* Diego Herranz, @diegoherranz
* Alexandre Oliveira, @RockyTV
* Konstantin Oblaukhov, @ObKo
* Jesper, @JeppeSRC
* Jacob E. F. Overgaard @JacobEFO
* Ed Peguillan III, @yankee14
* Thomas Schmid, @rckTom
* @mitch354
* Jan Krueger, @einball
* @dogtopus
* Darrell Harmon, @dlharmon
* David Imhoff, @dimhoff
* marble, @cyber-murmel
* @chemicstry
* @awygle
* @TiZed
* Sean Leavey, @SeanDS
* @Schlumpf
* Daniel Giesbrecht, @DanSGiesbrecht
* Caleb Reister, @calebreister
* Greg Cormier, @gcormier
* Ilya Elenskiy, @EvilMav
* Mathias Walter, @tolot27
* Michael Munch, @Munken
* @waschhauser
19 changes: 8 additions & 11 deletions KicadModTree/KicadFileHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def _serialize_Arc(self, node):

def _serialize_CirclePoints(self, node):
center_pos = node.getRealPosition(node.center_pos)
end_pos = node.getRealPosition(node.center_pos + (node.radius, 0))
end_pos = node.getRealPosition(node.end_pos)

return [
['center', center_pos.x, center_pos.y],
Expand Down Expand Up @@ -238,16 +238,13 @@ def _serialize_Text(self, node):
sexpr.append('hide')
sexpr.append(SexprSerializer.NEW_LINE)

effects = [
'effects',
['font',
['size', node.size.x, node.size.y],
['thickness', node.thickness]]]

if node.mirror:
effects.append(['justify', 'mirror'])

sexpr.append(effects)
sexpr.append(['effects',
['font',
['size', node.size.x, node.size.y],
['thickness', node.thickness]
]
]
) # NOQA
sexpr.append(SexprSerializer.NEW_LINE)

return sexpr
Expand Down
31 changes: 0 additions & 31 deletions KicadModTree/PolygonPoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,37 +143,6 @@ def cut(self, other):

self.nodes.insert(idx_self+1, other[idx_other])

def rotate(self, angle, origin=(0, 0), use_degrees=True):
r""" Rotate points around given origin

:params:
* *angle* (``float``)
rotation angle
* *origin* (``Vector2D``)
origin point for the rotation. default: (0, 0)
* *use_degrees* (``boolean``)
rotation angle is given in degrees. default:True
"""

for p in self.nodes:
p.rotate(angle=angle, origin=origin, use_degrees=use_degrees)
return self

def translate(self, distance_vector):
r""" Translate points

:params:
* *distance_vector* (``Vector2D``)
2D vector defining by how much and in what direction to translate.
"""

for p in self.nodes:
p += distance_vector
return self

def __copy__(self):
return PolygonPoints(nodes=self.nodes)

def __iter__(self):
for n in self.nodes:
yield n
Expand Down
102 changes: 2 additions & 100 deletions KicadModTree/Vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import warnings

from KicadModTree.util.kicad_util import formatFloat
from math import sqrt, sin, cos, hypot, atan2, degrees, radians
from math import sqrt


class Vector2D(object):
Expand Down Expand Up @@ -85,8 +85,7 @@ def distance_to(self, value):
:return: distance between self and other point
"""
other = Vector2D.__arithmetic_parse(value)
d = other - self
return hypot(d.x, d.y)
return sqrt((other.x - self.x)**2 + (other.y - self.y)**2)

@staticmethod
def __arithmetic_parse(value):
Expand Down Expand Up @@ -192,90 +191,6 @@ def __iter__(self):
def __copy__(self):
return Vector2D(self.x, self.y)

def rotate(self, angle, origin=(0, 0), use_degrees=True):
r""" Rotate vector around given origin

:params:
* *angle* (``float``)
rotation angle
* *origin* (``Vector2D``)
origin point for the rotation. default: (0, 0)
* *use_degrees* (``boolean``)
rotation angle is given in degrees. default:True
"""

op = Vector2D(origin)

if use_degrees:
angle = radians(angle)

temp = op.x + cos(angle) * (self.x - op.x) - sin(angle) * (self.y - op.y)
self.y = op.y + sin(angle) * (self.x - op.x) + cos(angle) * (self.y - op.y)
self.x = temp

return self

def to_polar(self, origin=(0, 0), use_degrees=True):
r""" Get polar representation of the vector

:params:
* *origin* (``Vector2D``)
origin point for polar conversion. default: (0, 0)
* *use_degrees* (``boolean``)
angle in degrees. default:True
"""

op = Vector2D(origin)

diff = self - op
radius = hypot(diff.x, diff.y)

angle = atan2(diff.y, diff.x)
if use_degrees:
angle = degrees(angle)

return (radius, angle)

@staticmethod
def from_polar(radius, angle, origin=(0, 0), use_degrees=True):
r""" Generate a vector from its polar representation

:params:
* *radius* (``float``)
lenght of the vector
* *angle* (``float``)
angle of the vector
* *origin* (``Vector2D``)
origin point for polar conversion. default: (0, 0)
* *use_degrees* (``boolean``)
angle in degrees. default:True
"""

if use_degrees:
angle = radians(angle)

x = radius * cos(angle)
y = radius * sin(angle)

return Vector2D({'x': x, 'y': y})+Vector2D(origin)

def to_homogeneous(self):
r""" Get homogeneous representation
"""

return Vector3D(self.x, self.y, 1)

@staticmethod
def from_homogeneous(source):
r""" Recover 2d vector from its homogeneous representation

:params:
* *source* (``Vector3D``)
3d homogeneous representation
"""

return Vector2D(source.x/source.z, source.y/source.z)


class Vector3D(Vector2D):
r"""Representation of a 3D Vector in space
Expand Down Expand Up @@ -349,19 +264,6 @@ def round_to(self, base):

return Vector3D([round(v / base) * base for v in self])

def cross_product(self, other):
other = Vector3D.__arithmetic_parse(other)

return Vector3D({
'x': self.y*other.z - self.z*other.y,
'y': self.z*other.x - self.x*other.z,
'z': self.x*other.y - self.y*other.x})

def dot_product(self, other):
other = Vector3D.__arithmetic_parse(other)

return self.x*other.x + self.y*other.y + self.z*other.z

@staticmethod
def __arithmetic_parse(value):
if isinstance(value, Vector3D):
Expand Down
58 changes: 23 additions & 35 deletions KicadModTree/nodes/base/Arc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,19 @@
from KicadModTree.Vector import *
from KicadModTree.nodes.Node import Node
import math
from KicadModTree.util.geometric_util import geometricArc, BaseNodeIntersection


class Arc(Node, geometricArc):
class Arc(Node):
r"""Add an Arc to the render tree

:param \**kwargs:
See below

:Keyword Arguments:
* *geometry* (``geometricArc``)
alternative to using geometric parameters
* *center* (``Vector2D``) --
center of arc
* *start* (``Vector2D``) --
start point of arc
* *midpoint* (``Vector2D``) --
alternative to start point
point is on arc and defines point of equal distance to both arc ends
arcs of this form are given as midpoint, center plus angle
* *end* (``Vector2D``) --
alternative to angle
arcs of this form are given as start, end and center
* *angle* (``float``) --
angle of arc
* *layer* (``str``) --
Expand All @@ -54,34 +44,13 @@ class Arc(Node, geometricArc):

def __init__(self, **kwargs):
Node.__init__(self)
geometricArc.__init__(self, **kwargs)
self.center_pos = Vector2D(kwargs['center'])
self.start_pos = Vector2D(kwargs['start'])
self.angle = kwargs['angle']

self.layer = kwargs.get('layer', 'F.SilkS')
self.width = kwargs.get('width')

def copyReplaceGeometry(self, geometry):
return Arc(geometry=geometry, layer=self.layer, width=self.width)

def copy(self):
return Arc(
center=self.center_pos, start=self.start_pos, angle=self.angle,
layer=self.layer, width=self.width
)

def cut(self, *other):
r""" cut line with given other element

:params:
* *other* (``Line``, ``Circle``, ``Arc``)
cut the element on any intersection with the given geometric element
"""
result = []
garcs = geometricArc.cut(self, *other)
for g in garcs:
result.append(self.copyReplaceGeometry(g))

return result

def calculateBoundingBox(self):
# TODO: finish implementation
min_x = min(self.start_pos.x, self._calulateEndPos().x)
Expand All @@ -107,6 +76,25 @@ def calculateBoundingBox(self):

return Node.calculateBoundingBox({'min': Vector2D((min_x, min_y)), 'max': Vector2D((max_x, max_y))})

def _calulateEndPos(self):
radius = self._calculateRadius()

angle = self._calculateStartAngle() + math.radians(self.angle)

return Vector2D(math.sin(angle)*radius, math.cos(angle)*radius)

def _calculateRadius(self):
x_size = self.start_pos.x - self.center_pos.x
y_size = self.start_pos.y - self.center_pos.y

return math.sqrt(math.pow(x_size, 2) + math.pow(y_size, 2))

def _calculateStartAngle(self):
x_size = self.start_pos.x - self.center_pos.x
y_size = self.start_pos.y - self.center_pos.y

return math.atan2(y_size, x_size)

def _getRenderTreeText(self):
render_strings = ['fp_arc']
render_strings.append(self.center_pos.render('(center {x} {y})'))
Expand Down
Loading