|
@@ -1,13 +1,14 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
-using System.Drawing;
|
|
|
+//using System.Drawing;
|
|
|
using System.Globalization;
|
|
|
+using System.Windows;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
-namespace SketchAssistant
|
|
|
+namespace SketchAssistantWPF
|
|
|
{
|
|
|
public class FileImporter
|
|
|
{
|
|
@@ -42,7 +43,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="fileName">the path of the input file</param>
|
|
|
/// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
|
|
|
- public (int, int, List<Line>) ParseISADInputFile(String fileName)
|
|
|
+public Tuple<int, int, List<InternalLine>> ParseISADInputFile(String fileName)
|
|
|
{
|
|
|
return ParseISADInput(System.IO.File.ReadAllLines(fileName));
|
|
|
}
|
|
@@ -52,7 +53,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
|
|
|
- private (int, int, List<Line>) ParseISADInput(String[] allLines)
|
|
|
+ private Tuple<int, int, List<InternalLine>> ParseISADInput(String[] allLines)
|
|
|
{
|
|
|
if (allLines.Length == 0)
|
|
|
{
|
|
@@ -66,9 +67,10 @@ namespace SketchAssistant
|
|
|
{
|
|
|
throw new FileImporterException("unterminated drawing definition", ".isad files have to end with the 'enddrawing' token", allLines.Length);
|
|
|
}
|
|
|
- (int, int) dimensions = ParseISADHeader(allLines);
|
|
|
- List<Line> picture = ParseISADBody(allLines, dimensions.Item1, dimensions.Item2);
|
|
|
- return (dimensions.Item1, dimensions.Item2, picture);
|
|
|
+ Tuple<int, int> dimensions = ParseISADHeader(allLines);
|
|
|
+ List<InternalLine> picture = ParseISADBody(allLines, dimensions.Item1, dimensions.Item2);
|
|
|
+
|
|
|
+ return new Tuple<int, int, List<InternalLine>>(dimensions.Item1, dimensions.Item2, picture);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -78,7 +80,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">the input file as an array of lines</param>
|
|
|
/// <returns>the width and height of the left canvas</returns>
|
|
|
- private (int, int) ParseISADHeader(String[] allLines)
|
|
|
+ private Tuple<int, int> ParseISADHeader(String[] allLines)
|
|
|
{
|
|
|
int width;
|
|
|
int height;
|
|
@@ -89,7 +91,7 @@ namespace SketchAssistant
|
|
|
String[] size = allLines[1].Split('x');
|
|
|
width = Convert.ToInt32(size[0]);
|
|
|
height = Convert.ToInt32(size[1]);
|
|
|
- return (width, height);
|
|
|
+ return new Tuple<int, int>(width, height);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -97,11 +99,11 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">the input file as an array of lines</param>
|
|
|
/// <returns>the parsed picture as a list of lines</returns>
|
|
|
- private List<Line> ParseISADBody(String[] allLines, int width, int height)
|
|
|
+ private List<InternalLine> ParseISADBody(String[] allLines, int width, int height)
|
|
|
{
|
|
|
String lineStartString = "line";
|
|
|
String lineEndString = "endline";
|
|
|
- List<Line> drawing = new List<Line>();
|
|
|
+ List<InternalLine> drawing = new List<InternalLine>();
|
|
|
//number of the line currently being parsed, enumeration starting at 0, body starts at the third line, therefore lin number 2
|
|
|
int i = 2;
|
|
|
//parse 'line' token and complete line definition
|
|
@@ -121,7 +123,7 @@ namespace SketchAssistant
|
|
|
//parse single point definition
|
|
|
if (!Regex.Match(allLines[i], @"^\d+;\d+$", RegexOptions.None).Success)
|
|
|
{
|
|
|
- throw new FileImporterException("invalid Point definition: wrong format", "format: [xCoordinate];[yCoordinate]", (i + 1) );
|
|
|
+ throw new FileImporterException("invalid Point definition: wrong format", "format: [xCoordinate];[yCoordinate]", (i + 1));
|
|
|
}
|
|
|
String[] coordinates = allLines[i].Split(';');
|
|
|
//no errors possible, convertability to int already checked above
|
|
@@ -129,7 +131,7 @@ namespace SketchAssistant
|
|
|
int yCoordinate = Convert.ToInt32(coordinates[1]);
|
|
|
if (xCoordinate < 0 || yCoordinate < 0 || xCoordinate > width - 1 || yCoordinate > height - 1)
|
|
|
{
|
|
|
- throw new FileImporterException("invalid Point definition: point out of bounds", null, (i + 1) );
|
|
|
+ throw new FileImporterException("invalid Point definition: point out of bounds", null, (i + 1));
|
|
|
}
|
|
|
newLine.Add(new Point(xCoordinate, yCoordinate));
|
|
|
//start parsing next line
|
|
@@ -138,12 +140,12 @@ namespace SketchAssistant
|
|
|
//"parse" 'endline' token, syntax already checked at the beginning, and start parsing next line
|
|
|
i++;
|
|
|
//add line to drawing
|
|
|
- drawing.Add(new Line(newLine));
|
|
|
+ drawing.Add(new InternalLine(newLine));
|
|
|
//update lineStartPointer to the presumable start of the next line
|
|
|
lineStartPointer = i;
|
|
|
}
|
|
|
//check if end of body is reached after there are no more line definitions
|
|
|
- if(i != allLines.Length - 1)
|
|
|
+ if (i != allLines.Length - 1)
|
|
|
{
|
|
|
throw new FileImporterException("missing or invalid line definition token", "line definitions start with the 'line' token", (i + 1));
|
|
|
}
|
|
@@ -156,7 +158,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
|
|
|
- public (int, int, List<Line>) ParseISADInputForTesting(String[] allLines)
|
|
|
+ public Tuple<int, int, List<InternalLine>> ParseISADInputForTesting(String[] allLines)
|
|
|
{
|
|
|
return ParseISADInput(allLines);
|
|
|
}
|
|
@@ -174,7 +176,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="fileName">the path of the input file</param>
|
|
|
/// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
|
|
|
- public (int, int, List<Line>) ParseSVGInputFile(String fileName, int windowWidth, int windowHeight)
|
|
|
+ public Tuple<int, int, List<InternalLine>> ParseSVGInputFile(String fileName, int windowWidth, int windowHeight)
|
|
|
{
|
|
|
return ParseSVGInput(System.IO.File.ReadAllLines(fileName), windowWidth, windowHeight);
|
|
|
}
|
|
@@ -184,35 +186,44 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
|
|
|
- private (int, int, List<Line>) ParseSVGInput(String[] allLines, double windowWidth, double windowHeight)
|
|
|
+ private Tuple<int, int, List<InternalLine>> ParseSVGInput(String[] allLines, double windowWidth, double windowHeight)
|
|
|
{
|
|
|
i = 0; //reset line pointer
|
|
|
if (allLines.Length == 0) //check for empty file
|
|
|
{
|
|
|
throw new FileImporterException("file is empty", "", -1);
|
|
|
}
|
|
|
- (int, int) sizedef = ParseSVGHeader(allLines); //parse svg file header and get internal coordinate range
|
|
|
+ var sizedef = ParseSVGHeader(allLines); //parse svg file header and get internal coordinate range
|
|
|
i++;
|
|
|
int width; //width of the resulting picture in pixels
|
|
|
int height; //height of the resulting picture in pixels
|
|
|
- if (windowWidth / windowHeight > sizedef.Item1 / sizedef.Item2) //height dominant, width has to be smaller than drawing window to preserve xy-scale
|
|
|
+ if(windowWidth != 0 && windowHeight != 0)
|
|
|
{
|
|
|
- scale = windowHeight / sizedef.Item2;
|
|
|
- height = (int)Math.Round(windowHeight);
|
|
|
- width = (int) Math.Round(scale * sizedef.Item1);
|
|
|
+ if (windowWidth / windowHeight > sizedef.Item1 / sizedef.Item2) //height dominant, width has to be smaller than drawing window to preserve xy-scale
|
|
|
+ {
|
|
|
+ scale = windowHeight / sizedef.Item2;
|
|
|
+ height = (int)Math.Round(windowHeight);
|
|
|
+ width = (int) Math.Round(scale * sizedef.Item1);
|
|
|
+ }
|
|
|
+ else //width dominant, height has to be smaller than drawing window to preserve xy-scale
|
|
|
+ {
|
|
|
+ scale = windowWidth / sizedef.Item1;
|
|
|
+ width = (int)Math.Round(windowWidth);
|
|
|
+ height = (int)Math.Round(scale * sizedef.Item2);
|
|
|
+ }
|
|
|
}
|
|
|
- else //width dominant, height has to be smaller than drawing window to preserve xy-scale
|
|
|
+ else
|
|
|
{
|
|
|
- scale = windowWidth / sizedef.Item1;
|
|
|
- width = (int)Math.Round(windowWidth);
|
|
|
- height = (int)Math.Round(scale * sizedef.Item2);
|
|
|
+ scale = 1;
|
|
|
+ width = sizedef.Item1;
|
|
|
+ height = sizedef.Item2;
|
|
|
}
|
|
|
- for(int j=0; j < allLines.Length; j++)
|
|
|
+ for (int j=0; j < allLines.Length; j++)
|
|
|
{
|
|
|
allLines[j] = allLines[j].Trim(whitespaces);
|
|
|
}
|
|
|
- List<Line> picture = ParseSVGBody(allLines); //parse whole svg drawing into list of lines
|
|
|
- return (width, height, picture);
|
|
|
+ List<InternalLine> picture = ParseSVGBody(allLines); //parse whole svg drawing into list of lines
|
|
|
+ return new Tuple<int, int, List<InternalLine>>(width, height, picture);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -220,7 +231,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the internal coordinate range of this drawing</returns>
|
|
|
- private (int, int) ParseSVGHeader(String[] allLines)
|
|
|
+ private Tuple<int, int> ParseSVGHeader(String[] allLines)
|
|
|
{
|
|
|
while (!allLines[i].StartsWith("<svg")) //skip non-relevant metadata at start of svg file
|
|
|
{
|
|
@@ -248,7 +259,7 @@ namespace SketchAssistant
|
|
|
{
|
|
|
throw new FileImporterException("missing height definition in SVG header", "the header should contain the \"height=...\" attribute", i + 1);
|
|
|
}
|
|
|
- return (width, height);
|
|
|
+ return new Tuple<int, int>(width, height);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -256,12 +267,12 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the parsed picture as a list of lines</returns>
|
|
|
- private List<Line> ParseSVGBody(String[] allLines)
|
|
|
+ private List<InternalLine> ParseSVGBody(String[] allLines)
|
|
|
{
|
|
|
- List<Line> picture = new List<Line>();
|
|
|
+ List<InternalLine> picture = new List<InternalLine>();
|
|
|
while (!allLines[i].StartsWith("</svg"))
|
|
|
{
|
|
|
- List<Line> element = ParseSingleSVGElement(allLines);
|
|
|
+ List<InternalLine> element = ParseSingleSVGElement(allLines);
|
|
|
if (element != null)
|
|
|
{
|
|
|
picture.AddRange(element);
|
|
@@ -277,7 +288,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the parsed Element as a list of lines</returns>
|
|
|
- private List<Line> ParseSingleSVGElement(string[] allLines)
|
|
|
+ private List<InternalLine> ParseSingleSVGElement(string[] allLines)
|
|
|
{
|
|
|
String[] currentElement = GetCurrentElement(allLines);
|
|
|
return ParseSingleLineSVGElement(currentElement);
|
|
@@ -288,10 +299,10 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the parsed element as a Line object, or null if the element is not supported</returns>
|
|
|
- private List<Line> ParseSingleLineSVGElement(string[] currentElement)
|
|
|
+ private List<InternalLine> ParseSingleLineSVGElement(string[] currentElement)
|
|
|
{
|
|
|
List<Point> points= null;
|
|
|
- List<Line> element = null;
|
|
|
+ List<InternalLine> element = null;
|
|
|
switch (currentElement[0])
|
|
|
{
|
|
|
case "<rect":
|
|
@@ -320,8 +331,8 @@ namespace SketchAssistant
|
|
|
}
|
|
|
if (element == null)
|
|
|
{
|
|
|
- element = new List<Line>();
|
|
|
- element.Add(new Line(points));
|
|
|
+ element = new List<InternalLine>();
|
|
|
+ element.Add(new InternalLine(points));
|
|
|
}
|
|
|
return element;
|
|
|
}
|
|
@@ -542,7 +553,7 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
/// <returns>the parsed element as a List of Points</returns>
|
|
|
- private List<Line> ParsePath(string[] currentElement)
|
|
|
+ private List<InternalLine> ParsePath(string[] currentElement)
|
|
|
{
|
|
|
List<String> pathElements = new List<string>();
|
|
|
for (int j = 0; j < currentElement.Length; j++)
|
|
@@ -560,7 +571,7 @@ namespace SketchAssistant
|
|
|
}
|
|
|
}
|
|
|
NormalizePathDeclaration(pathElements); //expand path data to always explicitly have the command descriptor in front of the appropriate number of arguments and to seperate command descriptors, coordinates and other tokens always into seperate list elements (equivalent to seperation with spaces in the input file, but svg allows also for comma as a seperator, and for omitting seperators where possible without losing information (refer to svg grammer) to reduce file size
|
|
|
- List<Line> element = new List<Line>();
|
|
|
+ List<InternalLine> element = new List<InternalLine>();
|
|
|
List<Point> currentLine = new List<Point>();
|
|
|
double lastBezierControlPointX= 0;
|
|
|
double lastBezierControlPointY= 0;
|
|
@@ -569,9 +580,9 @@ namespace SketchAssistant
|
|
|
double initialPositionX= -1;
|
|
|
double initialPositionY= -1;
|
|
|
bool newSubpath = true;
|
|
|
- (List<Point>, double, double) valuesArc; //list of points, new values for: lastPositionX, lastPositionY
|
|
|
- (List<Point>, double, double, double, double) valuesBezierCurve; //list of points, new values for: lastPositionX, lastPositionY, lastBezierControlPointX, lastBezierControlPointY
|
|
|
- (Point, double, double) valuesSinglePoint = Parse_M_L(pathElements); //new point, new values for: lastPositionX, lastPositionY
|
|
|
+ Tuple<List<Point>, double, double> valuesArc; //list of points, new values for: lastPositionX, lastPositionY
|
|
|
+ Tuple<List<Point>, double, double, double, double> valuesBezierCurve; //list of points, new values for: lastPositionX, lastPositionY, lastBezierControlPointX, lastBezierControlPointY
|
|
|
+ var valuesSinglePoint = Parse_M_L(pathElements); //new point, new values for: lastPositionX, lastPositionY
|
|
|
currentLine = new List<Point>();
|
|
|
currentLine.Add(valuesSinglePoint.Item1);
|
|
|
lastPositionX = valuesSinglePoint.Item2;
|
|
@@ -587,7 +598,7 @@ namespace SketchAssistant
|
|
|
currentToken = pathElements.First();
|
|
|
if (currentToken.Equals("M"))
|
|
|
{
|
|
|
- element.Add(new Line(currentLine)); //save current line
|
|
|
+ element.Add(new InternalLine(currentLine)); //save current line
|
|
|
valuesSinglePoint = Parse_M_L(pathElements);
|
|
|
currentLine = new List<Point>(); //create new empty line
|
|
|
currentLine.Add(valuesSinglePoint.Item1); //add point to new line
|
|
@@ -596,7 +607,7 @@ namespace SketchAssistant
|
|
|
}
|
|
|
else if (currentToken.Equals("m"))
|
|
|
{
|
|
|
- element.Add(new Line(currentLine)); //save current line
|
|
|
+ element.Add(new InternalLine(currentLine)); //save current line
|
|
|
valuesSinglePoint = Parse_m_l(pathElements, lastPositionX, lastPositionY);
|
|
|
currentLine = new List<Point>(); //create new empty line
|
|
|
currentLine.Add(valuesSinglePoint.Item1); //add point to new line
|
|
@@ -608,7 +619,7 @@ namespace SketchAssistant
|
|
|
valuesSinglePoint = Parse_Z(pathElements, initialPositionX, initialPositionY); //method call only used for uniform program structure... only real effect of method is to consume one token
|
|
|
newSubpath = true;
|
|
|
currentLine.Add(valuesSinglePoint.Item1); //add point to old line
|
|
|
- element.Add(new Line(currentLine)); //save current line
|
|
|
+ element.Add(new InternalLine(currentLine)); //save current line
|
|
|
currentLine = new List<Point>(); //create new empty line
|
|
|
currentLine.Add(valuesSinglePoint.Item1); //add point to new line
|
|
|
lastPositionX = valuesSinglePoint.Item2; //save last point coordinates
|
|
@@ -749,7 +760,7 @@ namespace SketchAssistant
|
|
|
}
|
|
|
if (currentLine.Count > 1)
|
|
|
{
|
|
|
- element.Add(new Line(currentLine)); //save current line
|
|
|
+ element.Add(new InternalLine(currentLine)); //save current line
|
|
|
}
|
|
|
return element;
|
|
|
}
|
|
@@ -961,10 +972,10 @@ namespace SketchAssistant
|
|
|
/// <param name="initialPositionX">absolute x coordinate of the last initial point of this subpath</param>
|
|
|
/// <param name="initialPositionY">absolute y coordinate of the last initial point of this subpath</param>
|
|
|
/// <returns></returns>
|
|
|
- private (Point, double, double) Parse_Z(List<string> pathElements, double initialPositionX, double initialPositionY)
|
|
|
+ private Tuple<Point, double, double> Parse_Z(List<string> pathElements, double initialPositionX, double initialPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
- return (ScaleAndCreatePoint(initialPositionX, initialPositionY), initialPositionX, initialPositionY);
|
|
|
+ return new Tuple<Point, double, double>(ScaleAndCreatePoint(initialPositionX, initialPositionY), initialPositionX, initialPositionY);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -972,14 +983,14 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
/// <param name="pathElements">a list of all not yet parsed path element tokens and values in correct order, starting with the element to be parsed</param>
|
|
|
/// <returns>the point at the end of the move, close loop or line action and its exact, unscaled coordinates</returns>
|
|
|
- private (Point, double, double) Parse_M_L(List<string> pathElements)
|
|
|
+ private Tuple<Point, double, double> Parse_M_L(List<string> pathElements)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse x coordinate
|
|
|
pathElements.RemoveAt(0); //remove x coordinate token
|
|
|
double y = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse y coordinate
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
- return (ScaleAndCreatePoint(x, y), x, y);
|
|
|
+ return new Tuple<Point, double, double>(ScaleAndCreatePoint(x, y), x, y);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -989,7 +1000,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>the point at the end of the move, close loop or line action and its exact, unscaled coordinates</returns>
|
|
|
- private (Point, double, double) Parse_m_l(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<Point, double, double> Parse_m_l(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse relative x coordinate
|
|
@@ -998,7 +1009,7 @@ namespace SketchAssistant
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
x = lastPositionX + x; //compute absolute x coordinate
|
|
|
y = lastPositionY + y; //compute absolute y coordinate
|
|
|
- return (ScaleAndCreatePoint(x, y), x, y);
|
|
|
+ return new Tuple<Point, double, double>(ScaleAndCreatePoint(x, y), x, y);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1007,12 +1018,12 @@ namespace SketchAssistant
|
|
|
/// <param name="pathElements">a list of all not yet parsed path element tokens and values in correct order, starting with the element to be parsed</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>the point at the end of the horizontal line action and its exact, unscaled coordinates</returns>
|
|
|
- private (Point, double, double) Parse_H(List<string> pathElements, double lastPositionY)
|
|
|
+ private Tuple<Point, double, double> Parse_H(List<string> pathElements, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse x coordinate
|
|
|
pathElements.RemoveAt(0); //remove x coordinate token
|
|
|
- return (ScaleAndCreatePoint(x, lastPositionY), x, lastPositionY);
|
|
|
+ return new Tuple<Point, double, double>(ScaleAndCreatePoint(x, lastPositionY), x, lastPositionY);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1022,13 +1033,13 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>the point at the end of the horizontal line action and its exact, unscaled coordinates</returns>
|
|
|
- private (Point, double, double) Parse_h(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<Point, double, double> Parse_h(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse relative x coordinate
|
|
|
pathElements.RemoveAt(0); //remove x coordinate token
|
|
|
x = lastPositionX + x; //compute absolute x coordinate
|
|
|
- return (ScaleAndCreatePoint(x, lastPositionY), x, lastPositionY);
|
|
|
+ return new Tuple<Point, double, double>(ScaleAndCreatePoint(x, lastPositionY), x, lastPositionY);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1037,12 +1048,12 @@ namespace SketchAssistant
|
|
|
/// <param name="pathElements">a list of all not yet parsed path element tokens and values in correct order, starting with the element to be parsed</param>
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <returns>the point at the end of the vertical line action and its exact, unscaled coordinates</returns>
|
|
|
- private (Point, double, double) Parse_V(List<string> pathElements, double lastPositionX)
|
|
|
+ private Tuple<Point, double, double> Parse_V(List<string> pathElements, double lastPositionX)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double y = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse y coordinate
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
- return (ScaleAndCreatePoint(lastPositionX, y), lastPositionX, y);
|
|
|
+ return new Tuple<Point, double, double>(ScaleAndCreatePoint(lastPositionX, y), lastPositionX, y);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1052,13 +1063,13 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>the point at the end of the vertical line action and its exact, unscaled coordinates</returns>
|
|
|
- private (Point, double, double) Parse_v(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<Point, double, double> Parse_v(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double y = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse relative y coordinate
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
y = lastPositionY + y; //compute absolute y coordinate
|
|
|
- return (ScaleAndCreatePoint(lastPositionX, y), lastPositionX, y);
|
|
|
+ return new Tuple<Point, double, double>(ScaleAndCreatePoint(lastPositionX, y), lastPositionX, y);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1068,7 +1079,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the second bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_C(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_C(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x1 = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse first control point x coordinate
|
|
@@ -1083,7 +1094,7 @@ namespace SketchAssistant
|
|
|
pathElements.RemoveAt(0); //remove x coordinate token
|
|
|
double y = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse target point y coordinate
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
- return (SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1093,7 +1104,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the second bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_c(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_c(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x1 = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse first control point x coordinate
|
|
@@ -1114,7 +1125,7 @@ namespace SketchAssistant
|
|
|
y2 = lastPositionY + y2; //compute absolute y coordinate
|
|
|
x = lastPositionX + x; //compute absolute x coordinate
|
|
|
y = lastPositionY + y; //compute absolute y coordinate
|
|
|
- return (SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1126,7 +1137,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastBezierControlPointX">absolute x coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <param name="lastBezierControlPointY">absolute y coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the second bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_S(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_S(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x2 = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse second control point x coordinate
|
|
@@ -1139,7 +1150,7 @@ namespace SketchAssistant
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
double x1 = lastPositionX + (lastPositionX - lastBezierControlPointX); //mirror last bezier control point at bezier start point to get first new bezier control point
|
|
|
double y1 = lastPositionY + (lastPositionY - lastBezierControlPointY); //mirror last bezier control point at bezier start point to get first new bezier control point
|
|
|
- return (SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1151,7 +1162,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastBezierControlPointX">absolute x coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <param name="lastBezierControlPointY">absolute y coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the second bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_s(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_s(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x2 = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse second control point x coordinate
|
|
@@ -1168,7 +1179,7 @@ namespace SketchAssistant
|
|
|
y2 = lastPositionY + y2; //compute absolute y coordinate
|
|
|
x = lastPositionX + x; //compute absolute x coordinate
|
|
|
y = lastPositionY + y; //compute absolute y coordinate
|
|
|
- return (SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleCubicBezier(lastPositionX, lastPositionY, x1, y1, x2, y2, x, y), x, y, x2, y2);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1178,7 +1189,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_Q(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_Q(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x1 = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse control point x coordinate
|
|
@@ -1189,7 +1200,7 @@ namespace SketchAssistant
|
|
|
pathElements.RemoveAt(0); //remove x coordinate token
|
|
|
double y = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse target point y coordinate
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
- return (SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1199,7 +1210,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_q(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_q(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x1 = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse control point x coordinate
|
|
@@ -1214,7 +1225,7 @@ namespace SketchAssistant
|
|
|
y1 = lastPositionY + y1; //compute absolute y coordinate
|
|
|
x = lastPositionX + x; //compute absolute x coordinate
|
|
|
y = lastPositionY + y; //compute absolute y coordinate
|
|
|
- return (SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1226,7 +1237,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastBezierControlPointX">absolute x coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <param name="lastBezierControlPointY">absolute y coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_T(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_T(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse target point x coordinate
|
|
@@ -1235,7 +1246,7 @@ namespace SketchAssistant
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
double x1 = lastPositionX + (lastPositionX - lastBezierControlPointX); //mirror last bezier control point at bezier start point to get first new bezier control point
|
|
|
double y1 = lastPositionY + (lastPositionY - lastBezierControlPointY); //mirror last bezier control point at bezier start point to get first new bezier control point
|
|
|
- return (SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1247,7 +1258,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastBezierControlPointX">absolute x coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <param name="lastBezierControlPointY">absolute y coordinate of the last bezier control point of the previous bezier curve</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the bezier curve, aswell as the unscaled x and y coordinates of the last point of the curve and of the bezier control point</returns>
|
|
|
- private (List<Point>, double, double, double, double) Parse_t(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
+ private Tuple<List<Point>, double, double, double, double> Parse_t(List<string> pathElements, double lastPositionX, double lastPositionY, double lastBezierControlPointX, double lastBezierControlPointY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double x = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse target point x coordinate
|
|
@@ -1258,7 +1269,7 @@ namespace SketchAssistant
|
|
|
y = lastPositionY + y; //compute absolute y coordinate
|
|
|
double x1 = lastPositionX + (lastPositionX - lastBezierControlPointX); //mirror last bezier control point at bezier start point to get first new bezier control point
|
|
|
double y1 = lastPositionY + (lastPositionY - lastBezierControlPointY); //mirror last bezier control point at bezier start point to get first new bezier control point
|
|
|
- return (SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
+ return new Tuple<List<Point>, double, double, double, double>(SampleQuadraticBezier(lastPositionX, lastPositionY, x1, y1, x, y), x, y, x1, y1);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1268,7 +1279,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the elliptic arc, aswell as the unscaled x and y coordinates of the last point of the arc<returns>
|
|
|
- private (List<Point>, double, double) Parse_A(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<List<Point>, double, double> Parse_A(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double rx = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse x radius
|
|
@@ -1287,7 +1298,7 @@ namespace SketchAssistant
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
x = x - lastPositionX; //compute relative x coordinate
|
|
|
y = y - lastPositionY; //compute relative y coordinate
|
|
|
- return (SampleArc(lastPositionX, lastPositionY, rx, ry, x, y, thetha, largeArcFlag, sweepFlag), x, y);
|
|
|
+ return new Tuple<List<Point>, double, double>(SampleArc(lastPositionX, lastPositionY, rx, ry, x, y, thetha, largeArcFlag, sweepFlag), x, y);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1297,7 +1308,7 @@ namespace SketchAssistant
|
|
|
/// <param name="lastPositionX">absolute x coordinate of the last active point</param>
|
|
|
/// <param name="lastPositionY">absolute y coordinate of the last active point</param>
|
|
|
/// <returns>a List of Points containing all sampled points on the elliptic arc, aswell as the unscaled x and y coordinates of the last point of the arc</returns>
|
|
|
- private (List<Point>, double, double) Parse_a(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
+ private Tuple<List<Point>, double, double> Parse_a(List<string> pathElements, double lastPositionX, double lastPositionY)
|
|
|
{
|
|
|
pathElements.RemoveAt(0); //remove element descriptor token
|
|
|
double rx = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse x radius
|
|
@@ -1314,7 +1325,7 @@ namespace SketchAssistant
|
|
|
pathElements.RemoveAt(0); //remove x coordinate token
|
|
|
double y = Convert.ToDouble(pathElements.First(), CultureInfo.InvariantCulture); //parse target point y coordinate
|
|
|
pathElements.RemoveAt(0); //remove y coordinate token
|
|
|
- return (SampleArc(lastPositionX, lastPositionY, rx, ry, x, y, thetha, largeArcFlag, sweepFlag), x, y);
|
|
|
+ return new Tuple<List<Point>, double, double>(SampleArc(lastPositionX, lastPositionY, rx, ry, x, y, thetha, largeArcFlag, sweepFlag), x, y);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1336,7 +1347,7 @@ namespace SketchAssistant
|
|
|
double sin = Math.Sin(thetha / 180 * Math.PI);
|
|
|
double targetXTransformed = cos * nextPositionXRelative - sin * nextPositionYRelative; //rotate target point counterclockwise around the start point by [thetha] degrees, thereby practically rotating an intermediate coordinate system, which has its origin in the start point, clockwise by the same amount
|
|
|
double targetYTransformed = sin * nextPositionXRelative + cos * nextPositionYRelative;
|
|
|
- (double[], double[]) values = SampleEllipticArcBiasedNoRotation(rx, ry, targetXTransformed, targetYTransformed, largeArcFlag, sweepFlag);
|
|
|
+ var values = SampleEllipticArcBiasedNoRotation(rx, ry, targetXTransformed, targetYTransformed, largeArcFlag, sweepFlag);
|
|
|
List<Point> result = new List<Point>();
|
|
|
for (int j = 0; j < values.Item1.Length; j++)
|
|
|
{
|
|
@@ -1359,10 +1370,10 @@ namespace SketchAssistant
|
|
|
/// <param name="largeArcFlag">flag determining if the large or the small arc is to be drawn</param>
|
|
|
/// <param name="sweepFlag">flag determining in which direction the arc is to be drawn (false = ccw, true = cw)</param>
|
|
|
/// <returns></returns>
|
|
|
- private (double[], double[]) SampleEllipticArcBiasedNoRotation(double rx, double ry, double targetXTransformed, double targetYTransformed, bool largeArcFlag, bool sweepFlag)
|
|
|
+ private Tuple<double[], double[]> SampleEllipticArcBiasedNoRotation(double rx, double ry, double targetXTransformed, double targetYTransformed, bool largeArcFlag, bool sweepFlag)
|
|
|
{
|
|
|
double xStretchFactor = rx / ry; //get rx to ry ratio
|
|
|
- (double[], double[]) values = SampleCircleArcBiasedNoRotation(ry, targetXTransformed / xStretchFactor, targetYTransformed, largeArcFlag, sweepFlag); //get a circular arc with radius ry
|
|
|
+ var values = SampleCircleArcBiasedNoRotation(ry, targetXTransformed / xStretchFactor, targetYTransformed, largeArcFlag, sweepFlag); //get a circular arc with radius ry
|
|
|
for (int j = 0; j < values.Item1.Length; j++)
|
|
|
{
|
|
|
values.Item1[j] = values.Item1[j] * xStretchFactor; //correct x coordinates to get an elliptical arc from a circular one
|
|
@@ -1379,7 +1390,7 @@ namespace SketchAssistant
|
|
|
/// <param name="largeArcFlag">flag determining if the large or the small arc is to be drawn</param>
|
|
|
/// <param name="sweepFlag">flag determining in which direction the arc is to be drawn (false = ccw, true = cw)</param>
|
|
|
/// <returns></returns>
|
|
|
- private (double[], double[]) SampleCircleArcBiasedNoRotation(double r, double nextPositionXRelative, double nextPositionYRelative, bool largeArcFlag, bool sweepFlag)
|
|
|
+ private Tuple<double[], double[]> SampleCircleArcBiasedNoRotation(double r, double nextPositionXRelative, double nextPositionYRelative, bool largeArcFlag, bool sweepFlag)
|
|
|
{
|
|
|
// code for center computation adapted from https://stackoverflow.com/a/36211852
|
|
|
double radsq = r * r;
|
|
@@ -1415,7 +1426,7 @@ namespace SketchAssistant
|
|
|
else xC = x3 - Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((nextPositionYRelative) / q);
|
|
|
if (yPlusFlag) yC = y3 + Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((nextPositionXRelative) / q); //y3 + Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((x2-x1) / q);
|
|
|
else yC = y3 - Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((nextPositionXRelative) / q);
|
|
|
- (double[], double[]) values = SampleCircleArcBiasedAroundCenter(-xC, -yC, nextPositionXRelative - xC, nextPositionYRelative - yC, r, largeArcFlag, sweepFlag);
|
|
|
+ var values = SampleCircleArcBiasedAroundCenter(-xC, -yC, nextPositionXRelative - xC, nextPositionYRelative - yC, r, largeArcFlag, sweepFlag);
|
|
|
for (int j = 0; j < values.Item1.Length; j++)
|
|
|
{
|
|
|
values.Item1[j] = values.Item1[j] + xC; //correct center point coordinate bias
|
|
@@ -1434,7 +1445,7 @@ namespace SketchAssistant
|
|
|
/// <param name="r">radius</param>
|
|
|
/// <param name="clockwise">direction</param>
|
|
|
/// <returns></returns>
|
|
|
- private (double[], double[]) SampleCircleArcBiasedAroundCenter(double xStartPoint, double yStartPoint, double xFinalPoint, double yFinalPoint, double r, bool largeArcFlag, bool clockwise)
|
|
|
+ private Tuple<double[], double[]> SampleCircleArcBiasedAroundCenter(double xStartPoint, double yStartPoint, double xFinalPoint, double yFinalPoint, double r, bool largeArcFlag, bool clockwise)
|
|
|
{
|
|
|
double phiEnd = Math.Atan2(yFinalPoint, xFinalPoint); // angles between points and origin and the positive x Axis
|
|
|
double phiStart = Math.Atan2(yStartPoint, xStartPoint);
|
|
@@ -1462,7 +1473,7 @@ namespace SketchAssistant
|
|
|
}
|
|
|
xValues[numberOfPoints - 1] = xFinalPoint; //(last segment always has an angle of less than or exactly 'angle')
|
|
|
yValues[numberOfPoints - 1] = yFinalPoint;
|
|
|
- return (xValues, yValues);
|
|
|
+ return new Tuple<double[], double[]>(xValues, yValues);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1479,12 +1490,12 @@ namespace SketchAssistant
|
|
|
/// <returns>a List of Points containing all sampled points</returns>
|
|
|
private List<Point> SampleCubicBezier(double lastPositionX, double lastPositionY, double controlPoint1X, double controlPoint1Y, double controlPoint2X, double controlPoint2Y, double nextPositionX, double nextPositionY)
|
|
|
{
|
|
|
- (double[], double[]) line1 = CreateDiscreteLine(lastPositionX, lastPositionY, controlPoint1X, controlPoint1Y);
|
|
|
- (double[], double[]) line2 = CreateDiscreteLine(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y);
|
|
|
- (double[], double[]) line3 = CreateDiscreteLine(controlPoint2X, controlPoint2Y, nextPositionX, nextPositionY);
|
|
|
- (double[], double[]) quadraticBezier1 = ComputeBezierStep(line1.Item1, line1.Item2, line2.Item1, line2.Item2);
|
|
|
- (double[], double[]) quadraticBezier2 = ComputeBezierStep(line2.Item1, line2.Item2, line3.Item1, line3.Item2);
|
|
|
- (double[], double[]) values = ComputeBezierStep(quadraticBezier1.Item1, quadraticBezier1.Item2, quadraticBezier2.Item1, quadraticBezier2.Item2);
|
|
|
+ var line1 = CreateDiscreteLine(lastPositionX, lastPositionY, controlPoint1X, controlPoint1Y);
|
|
|
+ var line2 = CreateDiscreteLine(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y);
|
|
|
+ var line3 = CreateDiscreteLine(controlPoint2X, controlPoint2Y, nextPositionX, nextPositionY);
|
|
|
+ var quadraticBezier1 = ComputeBezierStep(line1.Item1, line1.Item2, line2.Item1, line2.Item2);
|
|
|
+ var quadraticBezier2 = ComputeBezierStep(line2.Item1, line2.Item2, line3.Item1, line3.Item2);
|
|
|
+ var values = ComputeBezierStep(quadraticBezier1.Item1, quadraticBezier1.Item2, quadraticBezier2.Item1, quadraticBezier2.Item2);
|
|
|
List<Point> result = new List<Point>();
|
|
|
for (int j = 0; j < samplingRateBezier; j++)
|
|
|
{
|
|
@@ -1505,9 +1516,9 @@ namespace SketchAssistant
|
|
|
/// <returns>a List of Points containing all sampled points</returns>
|
|
|
private List<Point> SampleQuadraticBezier(double lastPositionX, double lastPositionY, double controlPointX, double controlPointY, double nextPositionX, double nextPositionY)
|
|
|
{
|
|
|
- (double[], double[]) line1 = CreateDiscreteLine(lastPositionX, lastPositionY, controlPointX, controlPointY);
|
|
|
- (double[], double[]) line2 = CreateDiscreteLine(controlPointX, controlPointY, nextPositionX, nextPositionY);
|
|
|
- (double[], double[]) values = ComputeBezierStep(line1.Item1, line1.Item2, line2.Item1, line2.Item2);
|
|
|
+ var line1 = CreateDiscreteLine(lastPositionX, lastPositionY, controlPointX, controlPointY);
|
|
|
+ var line2 = CreateDiscreteLine(controlPointX, controlPointY, nextPositionX, nextPositionY);
|
|
|
+ var values = ComputeBezierStep(line1.Item1, line1.Item2, line2.Item1, line2.Item2);
|
|
|
List<Point> result = new List<Point>();
|
|
|
for (int j = 0; j < samplingRateBezier; j++)
|
|
|
{
|
|
@@ -1524,17 +1535,17 @@ namespace SketchAssistant
|
|
|
/// <param name="point2X">x coordinate of point 2</param>
|
|
|
/// <param name="point2Y">y coordinate of point 2</param>
|
|
|
/// <returns>the discrete line as arrays of x and y coordinates</returns>
|
|
|
- private (double[], double[]) CreateDiscreteLine(double point1X, double point1Y, double point2X, double point2Y)
|
|
|
+ private Tuple<double[], double[]> CreateDiscreteLine(double point1X, double point1Y, double point2X, double point2Y)
|
|
|
{
|
|
|
double[] resultX = new double[samplingRateBezier];
|
|
|
double[] resultY = new double[samplingRateBezier];
|
|
|
for (int j = 0; j < samplingRateBezier; j++)
|
|
|
{
|
|
|
- (double, double) pointResult = LinearInterpolationForBezier(point1X, point1Y, point2X, point2Y, j);
|
|
|
+ var pointResult = LinearInterpolationForBezier(point1X, point1Y, point2X, point2Y, j);
|
|
|
resultX[j] = pointResult.Item1;
|
|
|
resultY[j] = pointResult.Item2;
|
|
|
}
|
|
|
- return (resultX, resultY);
|
|
|
+ return new Tuple<double[], double[]>(resultX, resultY);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1545,17 +1556,17 @@ namespace SketchAssistant
|
|
|
/// <param name="line2X">x coordinates of all points in line 2</param>
|
|
|
/// <param name="line2Y">y coordinates of all points in line 2</param>
|
|
|
/// <returns>the discrete bezier curve</returns>
|
|
|
- private (double[], double[]) ComputeBezierStep(double[] line1X, double[] line1Y, double[] line2X, double[] line2Y)
|
|
|
+ private Tuple<double[], double[]> ComputeBezierStep(double[] line1X, double[] line1Y, double[] line2X, double[] line2Y)
|
|
|
{
|
|
|
double[] resultX = new double[samplingRateBezier];
|
|
|
double[] resultY = new double[samplingRateBezier];
|
|
|
for (int j = 0; j < samplingRateBezier; j++)
|
|
|
{
|
|
|
- (double, double) pointResult = LinearInterpolationForBezier(line1X[j], line1Y[j], line2X[j], line2Y[j], j);
|
|
|
+ var pointResult = LinearInterpolationForBezier(line1X[j], line1Y[j], line2X[j], line2Y[j], j);
|
|
|
resultX[j] = pointResult.Item1;
|
|
|
resultY[j] = pointResult.Item2;
|
|
|
}
|
|
|
- return (resultX, resultY);
|
|
|
+ return new Tuple<double[], double[]>(resultX, resultY);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1567,12 +1578,12 @@ namespace SketchAssistant
|
|
|
/// <param name="point2Y">y coordinate of point 2</param>
|
|
|
/// <param name="j">number of point to be interpolated, at a total number of [samplingRateBezier] points</param>
|
|
|
/// <returns>the linearly interpolated point</returns>
|
|
|
- private (double, double) LinearInterpolationForBezier(double point1X, double point1Y, double point2X, double point2Y, int j)
|
|
|
+ private Tuple<double, double> LinearInterpolationForBezier(double point1X, double point1Y, double point2X, double point2Y, int j)
|
|
|
{
|
|
|
double factor = ((double)1 / (double)(samplingRateBezier - 1)) * (double)j; //factor for linear interpolation
|
|
|
double x = point1X + ((point2X - point1X) * factor);
|
|
|
double y = point1Y + ((point2Y - point1Y) * factor);
|
|
|
- return (x, y);
|
|
|
+ return new Tuple<double, double>(x, y);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1581,7 +1592,7 @@ namespace SketchAssistant
|
|
|
/// <param name="currentElement">the definition of the top level element as whitespace seperated String[]</param>
|
|
|
/// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
/// <returns>the parsed element as a Line object, or null if the element is not supported</returns>
|
|
|
- private List<Line> ParseMultiLineSVGElement(string[] currentElement, string[] allLines)
|
|
|
+ private List<InternalLine> ParseMultiLineSVGElement(string[] currentElement, string[] allLines)
|
|
|
{
|
|
|
throw new NotImplementedException();
|
|
|
}
|