File Coverage

blib/lib/Attach/Stuff.pm
Criterion Covered Total %
statement 34 34 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 45 45 100.0


line stmt bran cond sub pod time code
1             # Copyright (c) 2015 Timm Murray
2             # All rights reserved.
3             #
4             # Redistribution and use in source and binary forms, with or without
5             # modification, are permitted provided that the following conditions are met:
6             #
7             # * Redistributions of source code must retain the above copyright notice,
8             # this list of conditions and the following disclaimer.
9             # * Redistributions in binary form must reproduce the above copyright
10             # notice, this list of conditions and the following disclaimer in the
11             # documentation and/or other materials provided with the distribution.
12             #
13             # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14             # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15             # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16             # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17             # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18             # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19             # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20             # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21             # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22             # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23             # POSSIBILITY OF SUCH DAMAGE.
24             package Attach::Stuff;
25              
26             # ABSTRACT: Attach stuff to other stuff
27 2     2   17511 use v5.14;
  2         6  
  2         71  
28 2     2   9 use warnings;
  2         2  
  2         52  
29 2     2   1033 use Moose;
  2         737140  
  2         12  
30 2     2   12410 use namespace::autoclean;
  2         2311  
  2         10  
31 2     2   1134 use SVG;
  2         23001  
  2         14  
32              
33             # According to SVG spec, there are 3.543307 pixels per mm. See:
34             # http://www.w3.org/TR/SVG/coords.html#Units
35 2     2   1434 use constant MM_IN_PX => 3.543307;
  2         4  
  2         602  
36              
37             has 'width' => (
38             is => 'rw',
39             isa => 'Num',
40             required => 1,
41             );
42             has 'height' => (
43             is => 'rw',
44             isa => 'Num',
45             required => 1,
46             );
47             has 'screw_default_radius' => (
48             is => 'rw',
49             isa => 'Num',
50             required => 1,
51             );
52             has 'screw_holes' => (
53             is => 'rw',
54             isa => 'ArrayRef[ArrayRef[Num]]',
55             required => 1,
56             );
57              
58              
59             sub draw
60             {
61 1     1 1 6 my ($self) = @_;
62 1         34 my $width = $self->width;
63 1         27 my $height = $self->height;
64 1         29 my $screw_default_radius = $self->screw_default_radius;
65 1         2 my @screw_holes = @{ $self->screw_holes };
  1         30  
66              
67 1         5 my $svg = SVG->new(
68             width => $self->mm_to_px( $width ),
69             height => $self->mm_to_px( $height ),
70             );
71              
72 1         268 my $draw = $svg->group(
73             id => 'draw',
74             style => {
75             stroke => 'black',
76             'stroke-width' => 0.1,
77             fill => 'none',
78             },
79             );
80              
81             # Draw outline
82 1         55 $draw->rectangle(
83             x => 0,
84             y => 0,
85             width => $self->mm_to_px( $width ),
86             height => $self->mm_to_px( $height ),
87             );
88              
89             # Draw screw holes
90             $draw->circle(
91             cx => $self->mm_to_px( $_->[0] ),
92             cy => $self->mm_to_px( $_->[1] ),
93             r => $self->mm_to_px( $screw_default_radius ),
94 1         45 ) for @screw_holes;
95              
96 1         37 return $svg;
97             }
98              
99              
100             sub mm_to_px
101             {
102 10     10 1 43 my ($self, $mm) = @_;
103 10         32 return $mm * MM_IN_PX;
104             }
105              
106              
107 2     2   12 no Moose;
  2         4  
  2         18  
108             __PACKAGE__->meta->make_immutable;
109             1;
110             __END__
111              
112             =head1 NAME
113              
114             Attach::Stuff - Attach stuff to other stuff
115              
116             =head1 SYNOPSIS
117              
118             use Attach::Stuff;
119              
120             # You've got a board that's 26x34 mm, with two screw holes with a
121             # 2 mm diameter, spaced 3mm from the edge
122             my $attach = Attach::Stuff->new({
123             width => 26,
124             height => 34,
125             screw_default_radius => 1.25, # 2mm diameter, plus some wiggle room
126             screw_holes => [
127             [ 3, 3 ],
128             [ 26 - 3, 3 ],
129             ],
130             });
131             my $svg = $attach->draw;
132             print $svg->xmlify;
133              
134             =head1 DESCRIPTION
135              
136             You've got stuff, like a PCB board, that needs to be attached to other stuff,
137             like a lasercut enclosure. How do you attach the stuff to the other stuff?
138             This is a question we ask a lot when doing homebuilt Internet of Things
139             projects. Perl has the "Internet" half down pat. This module is an attempt to
140             improve the "Things" part.
141              
142             Lasercutters and other CNC machines often work with SVGs. Or more likely SVGs
143             can be converted into something that are converted into G-code by whatever turd
144             of a software package came with your CNC machine. Whatever the case, you can
145             probably start with an SVG and work your way from there.
146              
147             Before you can get there, you need measurements of the board and the location
148             of the screw holes. If you're lucky, you can find full schematics for your
149             board that will tell you the sizes exactly. If not, you'll need to get out
150             some callipers and possibly do some guesswork.
151              
152             Protip: if you had to guess on some of the locations, etch a prototype into
153             cardboard. Then you can lay the board over the cardboard and see if it matches
154             up right.
155              
156             =head1 METHODS
157              
158             =head2 new
159              
160             Constructor. Has the attributes below. Note that all lengths are measured
161             in millimeters.
162              
163             =over 4
164              
165             =item * width
166              
167             =item * height
168              
169             =item * screw_default_radius - All screws will be this radius. Currently, there is no way to specify a screw with any other radius. It's recommended to add a little extra to the radius to fit the screws through.
170              
171             =item * screw_holes - Arrayref of arrayrefs of the x/y coords of screw holes
172              
173             =back
174              
175             =head2 draw
176              
177             Draw based on the parameters given in the constructor. Returns an L<SVG>
178             object.
179              
180             =head2 mm_to_px
181              
182             Takes a measurement in millimeters and returns the length in pixels according
183             to the SVG standard. Useful if you need to draw more complex shapes for your
184             board after Attach::Stuff did the basics. See the C<examples/rpi_camera.pl>
185             file in this distribution for an example of this.
186              
187              
188             =head1 SEE ALSO
189              
190             L<SVG>
191              
192             =head1 LICENSE
193              
194              
195             Copyright (c) 2015, Timm Murray
196             All rights reserved.
197              
198             Redistribution and use in source and binary forms, with or without modification, are
199             permitted provided that the following conditions are met:
200              
201             * Redistributions of source code must retain the above copyright notice, this list of
202             conditions and the following disclaimer.
203             * Redistributions in binary form must reproduce the above copyright notice, this list of
204             conditions and the following disclaimer in the documentation and/or other materials
205             provided with the distribution.
206              
207             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
208             OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
209             MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
210             COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
211             EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
212             SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
213             HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
214             TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
215             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
216              
217             =cut