Make y scaling work (I think :P)

This commit is contained in:
Starbeamrainbowlabs 2017-12-03 15:51:22 +00:00
parent 42a03df794
commit 5daf2d0101
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
4 changed files with 79 additions and 17 deletions

View file

@ -8,6 +8,10 @@ namespace MusicBoxConverter
public class MusicBox
{
public string Name { get; private set; }
/// <summary>
/// The height of a strip for this music box, in millimetres.
/// </summary>
public float StripHeightMm = 58f;
public List<string> ValidNotes { get; private set; }
public Note LowestNote {

View file

@ -13,7 +13,7 @@ namespace MusicBoxConverter
public Vector2 offset { get; set; } = new Vector2(10, 10);
public Vector2 scaleFactor { get; set; } = new Vector2(0.1f, 4f);
public int holeSize { get; set; } = 3;
public float holeSize { get; set; } = 1f;
private int trackLength;
public int TrackLength
@ -46,6 +46,12 @@ namespace MusicBoxConverter
MusicBox = inMusicBox;
midiFile = MidiFile.Read(filename);
// Set the scale factor based on the strip height of the music box
scaleFactor = new Vector2(
scaleFactor.X,
MusicBox.StripHeightMm / MusicBox.NoteCount
);
foreach(Note note in AllNotes()) {
if (!MusicBox.IsValidNote(note))
Console.Error.WriteLine($"Warning: The note {note} at {note.Time} can't be played by the {MusicBox}.");
@ -55,14 +61,20 @@ namespace MusicBoxConverter
public void Output(string destinationFilename)
{
Vector2 area = new Vector2(TrackLength, MusicBox.NoteCount).Multiply(scaleFactor);
Vector2 size = area.Add(offset.Multiply(2)).Add(new Vector2(100000, 1000));
Vector2 size = area.Add(offset.Multiply(2));
SvgWriter svg = new SvgWriter(
destinationFilename,
$"{size.X}mm", $"{size.Y}mm"
);
svg.UnitSuffix = "mm";
SvgWriter svg = new SvgWriter(destinationFilename, size.X.ToString(), size.Y.ToString());
for(float i = 0; i < area.Y; i += scaleFactor.Y)
{
Vector2 start = offset.Add(new Vector2(0, i));
svg.WriteLine(start, start.Add(new Vector2(TrackLength * scaleFactor.X, 0)), "darkgreen", 1);
svg.WriteLine(start, start.Add(new Vector2(area.X, 0)), "darkgreen", 1);
}
svg.WriteRectangle(offset, area);
foreach(Note note in AllNotes())

View file

@ -5,11 +5,25 @@ using SBRL.Utilities;
namespace MusicBoxConverter
{
public class Rectangle
{
public Vector2 Start { get; set; }
public Vector2 Size { get; set; }
public Rectangle(Vector2 inStart, Vector2 inSize)
{
Start = inStart;
Size = inSize;
}
}
public class SvgWriter
{
public XmlWriter xml;
public SvgWriter(string outputFilename, string widthspec = "100%", string heightspec = "100%")
public string UnitSuffix { get; set; } = "";
public SvgWriter(string outputFilename, string widthspec = "100%", string heightspec = "100%", Rectangle viewBox = null)
{
xml = XmlWriter.Create(
outputFilename,
@ -20,8 +34,16 @@ namespace MusicBoxConverter
xml.WriteDocType("svg", "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd", null);
xml.WriteStartElement("svg", "http://www.w3.org/2000/svg");
xml.WriteAttributeString("version", "1.1");
xml.WriteAttributeString("x", "0");
xml.WriteAttributeString("y", "0");
xml.WriteAttributeString("width", widthspec);
xml.WriteAttributeString("height", heightspec);
if(viewBox != null) {
xml.WriteAttributeString(
"viewBox",
$"{viewBox.Start.X} {viewBox.Start.Y} {viewBox.Size.X} {viewBox.Size.Y}"
);
}
}
public void Complete()
@ -33,10 +55,27 @@ namespace MusicBoxConverter
public void WriteLine(Vector2 start, Vector2 end, string strokeStyle = "darkgreen", int strokeWidth = 3)
{
WritePath($"M{start.X} {start.Y} L {end.X} {end.Y}", strokeStyle, strokeWidth);
xml.WriteStartElement("line");
xml.WriteAttributeString("x1", $"{start.X}{UnitSuffix}");
xml.WriteAttributeString("y1", $"{start.Y}{UnitSuffix}");
xml.WriteAttributeString("x2", $"{end.X}{UnitSuffix}");
xml.WriteAttributeString("y2", $"{end.Y}{UnitSuffix}");
xml.WriteAttributeString("stroke", strokeStyle);
xml.WriteAttributeString("stroke-width", strokeWidth.ToString());
xml.WriteEndElement();
}
public void WritePath(string pathData, string strokeStyle = "green", int strokeWidth = 3)
public void StartScaleTransform(float scale)
{
xml.WriteStartElement("g");
xml.WriteAttributeString("transform", $"scale({scale})");
}
public void EndTransform()
{
xml.WriteEndElement();
}
/*public void WritePath(string pathData, string strokeStyle = "green", int strokeWidth = 3)
{
xml.WriteStartElement("path");
xml.WriteAttributeString("d", pathData);
@ -44,26 +83,26 @@ namespace MusicBoxConverter
xml.WriteAttributeString("stroke-width", strokeWidth.ToString());
xml.WriteAttributeString("fill", "transparent");
xml.WriteEndElement();
}
}*/
public void WriteRectangle(Vector2 position, Vector2 size, string strokeStyle = "red", int strokeWidth = 3)
{
xml.WriteStartElement("rect");
xml.WriteAttributeString("x", position.X.ToString());
xml.WriteAttributeString("y", position.Y.ToString());
xml.WriteAttributeString("width", size.X.ToString());
xml.WriteAttributeString("height", size.Y.ToString());
xml.WriteAttributeString("fill", "transparent");
xml.WriteAttributeString("x", $"{position.X}{UnitSuffix}");
xml.WriteAttributeString("y", $"{position.Y}{UnitSuffix}");
xml.WriteAttributeString("width", $"{size.X}{UnitSuffix}");
xml.WriteAttributeString("height", $"{size.Y}{UnitSuffix}");
xml.WriteAttributeString("fill", "none");
xml.WriteAttributeString("stroke", strokeStyle);
xml.WriteAttributeString("stroke-width", strokeWidth.ToString());
xml.WriteEndElement();
}
public void WriteCircle(Vector2 centre, int radius, string fillStyle = "blue")
public void WriteCircle(Vector2 centre, float radius, string fillStyle = "blue")
{
xml.WriteStartElement("circle");
xml.WriteAttributeString("cx", centre.X.ToString());
xml.WriteAttributeString("cy", centre.Y.ToString());
xml.WriteAttributeString("r", radius.ToString());
xml.WriteAttributeString("cx", $"{centre.X}{UnitSuffix}");
xml.WriteAttributeString("cy", $"{centre.Y}{UnitSuffix}");
xml.WriteAttributeString("r", $"{radius}{UnitSuffix}");
xml.WriteAttributeString("fill", fillStyle);
xml.WriteEndElement();
}

View file

@ -56,6 +56,13 @@ namespace SBRL.Utilities
Y / b
);
}
public Vector2 Divide(Vector2 b)
{
return new Vector2(
X / b.X,
Y / b.Y
);
}
public Vector2 Multiply(int b)
{
return new Vector2(