Skip to main content

My first SVG

SVG stands for Scalable Vector Graphics. It's a pretty common type of image.

Why?

For my project (recreation of an MPG-80), I need to cut a sheet of metal. Because the cut has to be precise, I choosed to use a laser cutting service. To do so, I need to produce a file (SVG) which represents the path of the laser beam.

My first idea was to vectorize with Inkscape the file I created with Gimp:

Gimp -> PNG file -> Inkscape -> SVG file -> FreeCAD

The result was poor, because the vectorization process created a lot of path (above 2000, whereas I have only 140 objects).

I definitely needed a more precise process. The idea was to create the SVG from scratch:
1- precisely measuring the coordinates of all the objects (holes)
2- creating a SVG file from scratch with Inkscape
3- importing the file in FreeCAD

Fortunately, all the objects I need to cut  boxes, circles and paths (shapes bazed on Bezier curves) and all are symmetrical around vertical and horizontal axis (top is symmetrical to bottom, left to right). So with Gimp, I measured precisely the coordinates of the centers of all objects. I ended up with a LibreOffice spreadsheet.

 

 First try...

My attempt to created the SVG with Inkscape went nowehere. Happily, I quick search on Google shows writing a SVG file is rather simple. Here is my first SVG:

  <svg height="100" width="100">
    <circle cx="100" cy="100" r="100" style="fill:rgb(192,192,255);stroke:none;stroke-width:1" />
    <rect x="0" y="0" width="40" height="40" style="fill:rgb(147,147,255);stroke:none;stroke-width:1" />
    <rect x="16" y="16" width="35" height="35" style="fill:rgb(127,127,245);stroke:none;stroke-width:1" />
    <rect x="32" y="32" width="27" height="27" style="fill:rgb(107,107,235);stroke:none;stroke-width:1" />
    <rect x="48" y="48" width="17" height="17" style="fill:rgb(87,87,225);stroke:none;stroke-width:1" />
  </svg>

The result is:

Full documentation available here: https://developer.mozilla.org/en-US/docs/Web/SVG

The spreasheet

For my project, I need to cut 3 sheets: the casing (metal, 1.3 mm), a plastic sheet (lexan) containg the silkscreen, and another metal sheet holding the PCB. The need for 2 metal sheets is leaded to the fact by buttons are enclosed between the two sheets. The coordinate set is differents for each sheet.

In my spreasheet, the columns were:
A: Object Id (unused)
B: Object Label (unused)
C: Object Type on sheet 1 & 2: rect, circle or path
D: Object Type on sheet 3: rect, circle or path
E: Object width in mm
F: Object height in mm
G: Object absolute x in mm
H: Object absolute y in mm
I:  Object x relative to the casing (identical to G)
J:  Object y relative to the casing (identical to H)
K: SVG code for the objects, relative to the casing
L: Object x relative to the silkscreen
M: Object y relative to the silkscreen
N: SVG code for the objects, relative to the silkscreen

In column K, I created a formula to generate all the paths:
="<" & $C4 &
     IF($C4="rect",
  " x=""" & ROUND(Params.$B$1*(L4-$E4/2),3) & """" &
  " y=""" & ROUND(Params.$B$1*(M4-$F4/2),3) & """" &
  " width=""" & ROUND(Params.$B$1*($E4),3) & """" &
  " height=""" & ROUND(Params.$B$1*($F4),3),
     IF($C4="circle",
  " cx=""" & ROUND(Params.$B$1*(L4),3) & """" &
  " cy=""" & ROUND(Params.$B$1*(M4),3) & """" &
  " r=""" & ROUND(Params.$B$1*($F4/2),3),
     IF($C4="path",
  " d=""M" & ROUND(Params.$B$1*(L4-$E4/2),3) & "," & ROUND(Params.$B$1*(M4-$F4/2+Params.$B$2),3) &
  " C" & ROUND(Params.$B$1*(L4-$E4/2),3) & "," & ROUND(Params.$B$1*(M4-$F4/2),3) &
   " " & ROUND(Params.$B$1*(L4+$E4/2),3) & "," & ROUND(Params.$B$1*(M4-$F4/2),3) &
   " " & ROUND(Params.$B$1*(L4+$E4/2),3) & "," & ROUND(Params.$B$1*(M4-$F4/2+Params.$B$2),3) &
  " L" & ROUND(Params.$B$1*(L4+$E4/2),3) & "," & ROUND(Params.$B$1*(M4+$F4/2-Params.$B$2),3) &
  " C" & ROUND(Params.$B$1*(L4+$E4/2),3) & "," & ROUND(Params.$B$1*(M4+$F4/2),3) &
   " " & ROUND(Params.$B$1*(L4-$E4/2),3) & "," & ROUND(Params.$B$1*(M4+$F4/2),3) &
   " " & ROUND(Params.$B$1*(L4-$E4/2),3) & "," & ROUND(Params.$B$1*(M4+$F4/2-Params.$B$2),3) &
   " L" & ROUND(Params.$B$1*(L4-$E4/2),3) & "," & ROUND(Params.$B$1*(M4-$F4/2+Params.$B$2),3), "" )))
 & """ " &Params.$B$3&" />"


Where Params.$B$1 contains a scaling ratio (90*177/(25.4*270)=2.3228346457) and Params.$B$2 contains a rounding factor for the path objects.
This gave the following result (abstract):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="1012.756" height="411.142" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:ev="http://www.w3.org/2001/xml-events"
    version="1.1"
    baseProfile="full">

<rect x="50.998" y="358.762"
    width="25.296"

    height="12.311"
    style="fill:#000000;fill-opacity:1;
        fill-rule:evenodd;stroke:none;
        stroke-width:1px;stroke-linecap:butt;
        stroke-linejoin:miter;stroke-opacity:1" />
<circle cx="63.646" cy="347.264" r="3.484"
    style="fill:#000000;fill-opacity:1;
        fill-rule:evenodd;stroke:none;
        stroke-width:1px;stroke-linecap:butt;
        stroke-linejoin:miter;stroke-opacity:1" />
...
<path d="M115.213,206.616
    C115.213,201.97 123.343,201.97 123.343,206.616
    L123.343,286.754
    C123.343,291.4 115.213,291.4 115.213,286.754
    L115.213,206.616"
    style="fill:#000000;fill-opacity:1;
        fill-rule:evenodd;stroke:none;
        stroke-width:1px;stroke-linecap:butt;
        stroke-linejoin:miter;stroke-opacity:1" />
...


Nice! The fact I had to repeat the style tag on every line is due to a bug when importing in FreeCAD.

The overall result is the following:


A closer look:


In FreeCAD, I could create the casing:

Comments

Popular posts from this blog

Update to Ubuntu 24.04

After years running Ubuntu 20.04, I recently (January 2025) installed Ubuntu 24.04 Noble Numbat. This cames with few improvements and a couple of disappointments, mainly the lost of my dual-screen: my graphic card, Nvidia Quadro FX3700, is not supported anymore by the latest driver. The result is: when the computer boots up, it does on output 0 (right screen). But as soon as Wayland starts, it switches to output 1 (left screen), ignoring the other output; my right screen remains black. This is a new behavior, it works fine on 20.04. Keyboard I write mainly in French and English. My keyboard is US Qwerty with US International layout. In English, what I see on keyboard is what I get on screen. In French, the diacritics are obtained with compositional keys: To get Ubuntu 20 Ubuntu 24 á é í ó ú ý Á É Í Ó Ú Ý ' e (Quote letter) ' E (Quote shift+letter) à è ...

Drive replacement for Fostex DMT8-vl

The IDE hard drive on my Fostex DMT8-vl multitrack recorder shows signs of its imminent death; when getting hot, I could not record anymore. Must be said this drive comes from an old Sun Station, and has been replaced because I/O failures were detected by Solaris. It worked at least 5 years in my recorder: not so bad. However, time is now to replace it. The DMT8-vl is not able to handle drives bigger than 8.4 GB. Well, it is able to (the current drive is 15 GB), but only 8.4 GB will be usable. My tought was to use a 8 GB CompactFlash; having no moving parts means no noise, which is quite temptating for a music recording device. I purchased a CompactFlash-IDE adapter on the internet (8$) and I had to build a male-male IDE cable adapter (4$). Unfortunately, this doesn't work. The drive is correctly discovered by the operating system, which proposes to format it ("format IDE?"). After answering "yes", the formating runs pretty fast (faster than on a real drive), ...

My journey with ATtiny4313 (part 1)

Introduction The context For a personal project, I want to program an Atmel ATtiny4313 microcontroller. I use microcontrollers for several years, but not on a regular basis (maybe 3-4 times a year), mostly for testing and generally with a deceptive result. But failure isn't the best training? This article aims to share my errors and success, as well as being a personal log. The project The project is to replace the main board of a Soundpool MO4, a MIDI OUT extension for the Atari ST; details here . Overall, the project is pretty simple: reading the parallel port and copy verbatim the data to MIDI out. This is the reason behind my choice of this particular microcontroller, since it embeds an USART and has an 8 bits parallel port (20 pins DIP package). The MO4 having 4 MIDI Outs, I will use 4 ATTiny4313, one for each out; this is actually cheaper than finding a 4-channel USART. Each microcontroller must determine if the data present on the parallel port shoul...