class HumbuckerDiMarzioF(HumbuckerDiMarzio): """Geometry for most Di Marzio F-spaced humbuckers. https://d2emr0qhzqfj88.cloudfront.net/s3fs-public/diagrams/DMHBdim_0.pdf """ string_spacing: float = inches_to_mm(0.402)
def string_tension(length, diameter, frequency, density=STAINLESS_STEEL_DENSITY): """ """ linear_density = 1.e-12 * density * numpy.pi * inches_to_mm( diameter)**2 / 4. return 4. * length**2. * frequency**2. * linear_density
class HumbuckerEMG(HumbuckerBase): """Geometry for most EMG humbuckers. https://www.emgpickups.com/pub/media/Mageants/h/x/hx_0230-0110re.pdf """ inner_length: float = 38.1 inner_width: float = 69.8 outer_length: float = inner_length outer_width: float = 83.0 # TBC string_spacing: float = inches_to_mm(0.383) # TBC screw_spacing: float = 78.5 wing_length: float = inches_to_mm(0.500) # TBC def draw(self, offset): """Overloaded method. """ self.draw_screw_holes(offset) RoundedRectangle((0., 0.), self.inner_length, self.inner_width, self.corner_radius).draw(offset) self.draw_wings(offset)
def data_frame(self, scale_length, tuning=GUITAR_STANDARD_TUNING): """Return a pandas data frame with all the relevant info. """ tensions = self.tensions(scale_length, tuning) data = { 'Note': tuning.notes, 'Diameter [in]': self.diameters, 'Diameter [mm]': inches_to_mm(self.diameters), 'Frequency [Hz]': tuning.frequencies, 'Tension [N]': tensions, 'Tension [lb]': newton_to_pounds(tensions) } return pd.DataFrame(data=data)
class SingleCoilDiMarzio(SingleCoilBase): """Geometry for Di Marzio Strat single coils. https://d2emr0qhzqfj88.cloudfront.net/s3fs-public/diagrams/scdimensions_0.pdf """ inner_length: float = inches_to_mm(0.69) inner_width: float = inches_to_mm(2.74) outer_length: float = inches_to_mm(0.90) outer_width: float = inches_to_mm(3.28) string_spacing: float = inches_to_mm(0.406) screw_spacing: float = inches_to_mm(3.02)
class FenderStratocasterContour(HeadstockContourBase): """Contour for the Fender Stratocaster headstock. """ DEFAULT_PAR_DICT = { 'width_at_nut': inches_to_mm(1.650), 'd1': 8.06, 'r1': 15.23, 'span1': 70.0, 'r2': 7.20, 'span2': 87.0, 'd2': 143.00, 'r3': 25.50, 'span3': 233.0, 'r4': 8.45, 'span4': 77.5, 'r5': 280.40, 'span5': 8.0, 'r6': 169.60, 'span6': 13.2, 'r7': 50.50 } def construct(self): """Overloaded method. """ p1 = self.anchor.vmove(0.5 * self.width_at_nut) p2 = p1.hmove(self.d1) line1 = Line(p1, p2) arc1 = line1.connecting_circular_arc(self.r1, self.span1) arc2 = arc1.connecting_circular_arc(-self.r2, self.span2) line2 = arc2.connecting_line(self.d2) arc3 = line2.connecting_circular_arc(-self.r3, -self.span3) arc4 = arc3.connecting_circular_arc(self.r4, -self.span4) arc5 = arc4.connecting_circular_arc(self.r5, self.span5) arc6 = arc5.connecting_circular_arc(-self.r6, self.span6) # Last circle---here things are a little bit tricky :-) p = arc6.end_point() phi = np.degrees( np.arccos(1. - (-0.5 * self.width_at_nut - p.y) / self.r7)) dx = self.r7 * np.sin(np.radians(phi)) c7 = Point(p.x - dx, -0.5 * self.width_at_nut - self.r7) arc7 = CircularArc(c7, self.r7, 90. - phi, phi) line3 = arc7.connecting_line(arc7.end_point().x) return locals()
class HumbuckerSeymourDuncan(HumbuckerBase): """Geometry for most Seymour Duncan humbuckers. https://www.seymourduncan.com/wp-content/uploads/2019/08/HB-6-String-Uncovered-Short-Magnet-Long-Leg-Bottom-Plate.gif """ inner_length: float = inches_to_mm(1.438) inner_width: float = inches_to_mm(2.695) outer_length: float = inner_length outer_width: float = inches_to_mm(3.315) string_spacing: float = inches_to_mm(0.385) screw_spacing: float = inches_to_mm(3.063) wing_length: float = inches_to_mm(0.500)
class HumbuckerDiMarzio(HumbuckerBase): """Geometry for most Di Marzio humbuckers. https://d2emr0qhzqfj88.cloudfront.net/s3fs-public/diagrams/DMHBdim_0.pdf """ inner_length: float = inches_to_mm(1.5) inner_width: float = inches_to_mm(2.7) outer_length: float = inner_length outer_width: float = inches_to_mm(3.32) string_spacing: float = inches_to_mm(0.383) screw_spacing: float = inches_to_mm(3.1) wing_length: float = inches_to_mm(0.515)
def load_data(self): """ """ file_path = os.path.join(TEST_DATA_FOLDER, 'headstock_fender_profile.txt') x, y = np.loadtxt(file_path, unpack=True, delimiter=',') scale = (x.max() - x.min()) / inches_to_mm(7.313) xoffset = x.min() yoffset = 0.5 * (y[0] + y[-1]) def to_physical_coordinates(x, y): """ """ return (x - xoffset) / scale, -(y - yoffset) / scale x, y = to_physical_coordinates(x, y) file_path = os.path.join(TEST_DATA_FOLDER, 'headstock_fender_holes.txt') xh, yh = np.loadtxt(file_path, unpack=True, delimiter=',') xh, yh = to_physical_coordinates(xh, yh) return x, y, xh, yh
"""String formatting """ text = f'String gauge {self.name}\n' for i, d in enumerate(self.diameters): text += f'{i} -> {d:.3f} in ({inches_to_mm(d):.3f} mm)\n' return text class StandardStringGauges: EXTRA_SUPER_LIGHT = StringGauge('Extra super light', [.008, .010, .015, .021, .030, .038]) LIGHT = StringGauge('Light', [.009, .011, .016, .024, .032, .042]) LIGHT_REGULAR = StringGauge('Light regular', [.009, .011, .016, .026, .036, .046]) REGULAR = StringGauge('Regular', [.010, .013, .017, .026, .036, .046]) REGULAR_HEAVY = StringGauge('Regular heavy', [.010, .013, .017, .032, .042, .052]) MEDIUM = StringGauge('Medium', [.011, .014, .018, .028, .038, .049]) HEAVY = StringGauge('Heavy', [.012, .016, .024, .032, .042, .052]) if __name__ == '__main__': print(newton_to_pounds(string_tension(648., 0.009, 329.63))) A = 1.e-12 * STAINLESS_STEEL_DENSITY * numpy.pi * inches_to_mm(1.)**2. print(A) print(newton_to_pounds(A * (648. * 0.009 * 329.63)**2.)) print(StandardStringGauges.LIGHT_REGULAR) print(StandardStringGauges.LIGHT_REGULAR.tensions(648.)) print(newton_to_pounds(StandardStringGauges.LIGHT_REGULAR.tensions(648.)))
def test_roundtrip(self, value: float = 648.) -> None: """Test roundtrip. """ self.assertAlmostEqual(inches_to_mm(mm_to_inches(value)), value)
def test_simple(self) -> None: """Basic test. """ self.assertAlmostEqual(inches_to_mm(1.), 25.4) self.assertAlmostEqual(mm_to_inches(1.), 0.0393701)