public override IEnumerable <SvgAttribute> GetAttributes() { var baseAttributes = base.GetAttributes(); if (baseAttributes != null) { foreach (var attr in baseAttributes) { yield return(attr); } } var ci = CultureInfo.InvariantCulture; yield return(new SvgAttribute("fit-to-path", null, XmlNamespace.AurigmaVectorObjects, () => FitToPath.ToString(ci), v => FitToPath = SvgAttribute.ParseBooleanAttribute(v) )); yield return(new SvgAttribute("stretch", null, XmlNamespace.AurigmaVectorObjects, () => Stretch.ToString(ci), v => Stretch = SvgAttribute.ParseBooleanAttribute(v) )); yield return(new SvgAttribute("original-font-size", "0", XmlNamespace.AurigmaVectorObjects, () => OriginalFontSize.ToString(ci), v => OriginalFontSize = SvgAttribute.ParseFloatAttribute(v) )); yield return(new SvgAttribute("fit-to-path-step", "1", XmlNamespace.AurigmaVectorObjects, () => FitToPathStep.ToString(ci), v => FitToPathStep = SvgAttribute.ParseFloatAttribute(v) )); yield return(new SvgAttribute("path-start", "0", XmlNamespace.AurigmaVectorObjects, () => PathStart.ToString(ci), v => PathStart = SvgAttribute.ParseFloatAttribute(v) )); yield return(new SvgAttribute("path-end", "1", XmlNamespace.AurigmaVectorObjects, () => PathEnd.ToString(ci), v => PathEnd = SvgAttribute.ParseFloatAttribute(v) )); }
/// <summary> /// Creates between 1 and 5 Béziers curves from parameters specified like in WPF. /// </summary> public static List <XPoint> BezierCurveFromArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArc, bool clockwise, PathStart pathStart) { // See also http://www.charlespetzold.com/blog/blog.xml from January 2, 2008: // http://www.charlespetzold.com/blog/2008/01/Mathematics-of-ArcSegment.html double δx = size.Width; double δy = size.Height; Debug.Assert(δx * δy > 0); double factor = δy / δx; bool isCounterclockwise = !clockwise; // Adjust for different radii and rotation angle. XMatrix matrix = new XMatrix(); matrix.RotateAppend(-rotationAngle); matrix.ScaleAppend(δy / δx, 1); XPoint pt1 = matrix.Transform(point1); XPoint pt2 = matrix.Transform(point2); // Get info about chord that connects both points. XPoint midPoint = new XPoint((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2); XVector vect = pt2 - pt1; double halfChord = vect.Length / 2; // Get vector from chord to center. XVector vectRotated; // (comparing two Booleans here!) if (isLargeArc == isCounterclockwise) { vectRotated = new XVector(-vect.Y, vect.X); } else { vectRotated = new XVector(vect.Y, -vect.X); } vectRotated.Normalize(); // Distance from chord to center. double centerDistance = Math.Sqrt(δy * δy - halfChord * halfChord); if (double.IsNaN(centerDistance)) { centerDistance = 0; } // Calculate center point. XPoint center = midPoint + centerDistance * vectRotated; // Get angles from center to the two points. double α = Math.Atan2(pt1.Y - center.Y, pt1.X - center.X); double β = Math.Atan2(pt2.Y - center.Y, pt2.X - center.X); // (another comparison of two Booleans!) if (isLargeArc == (Math.Abs(β - α) < Math.PI)) { if (α < β) { α += 2 * Math.PI; } else { β += 2 * Math.PI; } } // Invert matrix for final point calculation. matrix.Invert(); double sweepAngle = β - α; // Let the algorithm of GDI+ DrawArc to Bézier curves do the rest of the job return(BezierCurveFromArc(center.X - δx * factor, center.Y - δy, 2 * δx * factor, 2 * δy, α / Calc.Deg2Rad, sweepAngle / Calc.Deg2Rad, pathStart, ref matrix)); }
/// <summary> /// Appends a Bézier curve for an arc within a full quadrant. /// </summary> static void AppendPartialArcQuadrant(List <XPoint> points, double x, double y, double width, double height, double α, double β, PathStart pathStart, XMatrix matrix) { Debug.Assert(α >= 0 && α <= 360); Debug.Assert(β >= 0); if (β > 360) { β = β - Math.Floor(β / 360) * 360; } Debug.Assert(Math.Abs(α - β) <= 90); // Scanling factor. double δx = width / 2; double δy = height / 2; // Center of ellipse. double x0 = x + δx; double y0 = y + δy; // We have the following quarters: // | // 2 | 3 // ----+----- // 1 | 0 // | // If the angles lie in quarter 2 or 3, their values are subtracted by 180 and the // resulting curve is reflected at the center. This algorithm works as expected (simply tried out). // There may be a mathematically more elegant solution... bool reflect = false; if (α >= 180 && β >= 180) { α -= 180; β -= 180; reflect = true; } double cosα, cosβ, sinα, sinβ; if (width == height) { // Circular arc needs no correction. α = α * Calc.Deg2Rad; β = β * Calc.Deg2Rad; } else { // Elliptic arc needs the angles to be adjusted such that the scaling transformation is compensated. α = α * Calc.Deg2Rad; sinα = Math.Sin(α); if (Math.Abs(sinα) > 1E-10) { α = Math.PI / 2 - Math.Atan(δy * Math.Cos(α) / (δx * sinα)); } β = β * Calc.Deg2Rad; sinβ = Math.Sin(β); if (Math.Abs(sinβ) > 1E-10) { β = Math.PI / 2 - Math.Atan(δy * Math.Cos(β) / (δx * sinβ)); } } double κ = 4 * (1 - Math.Cos((α - β) / 2)) / (3 * Math.Sin((β - α) / 2)); sinα = Math.Sin(α); cosα = Math.Cos(α); sinβ = Math.Sin(β); cosβ = Math.Cos(β); //XPoint pt1, pt2, pt3; if (!reflect) { // Calculation for quarter 0 and 1. switch (pathStart) { case PathStart.MoveTo1st: points.Add(matrix.Transform(new XPoint(x0 + δx * cosα, y0 + δy * sinα))); break; case PathStart.LineTo1st: points.Add(matrix.Transform(new XPoint(x0 + δx * cosα, y0 + δy * sinα))); break; case PathStart.Ignore1st: break; } points.Add(matrix.Transform(new XPoint(x0 + δx * (cosα - κ * sinα), y0 + δy * (sinα + κ * cosα)))); points.Add(matrix.Transform(new XPoint(x0 + δx * (cosβ + κ * sinβ), y0 + δy * (sinβ - κ * cosβ)))); points.Add(matrix.Transform(new XPoint(x0 + δx * cosβ, y0 + δy * sinβ))); } else { // Calculation for quarter 2 and 3. switch (pathStart) { case PathStart.MoveTo1st: points.Add(matrix.Transform(new XPoint(x0 - δx * cosα, y0 - δy * sinα))); break; case PathStart.LineTo1st: points.Add(matrix.Transform(new XPoint(x0 - δx * cosα, y0 - δy * sinα))); break; case PathStart.Ignore1st: break; } points.Add(matrix.Transform(new XPoint(x0 - δx * (cosα - κ * sinα), y0 - δy * (sinα + κ * cosα)))); points.Add(matrix.Transform(new XPoint(x0 - δx * (cosβ + κ * sinβ), y0 - δy * (sinβ - κ * cosβ)))); points.Add(matrix.Transform(new XPoint(x0 - δx * cosβ, y0 - δy * sinβ))); } }
/// <summary> /// Creates between 1 and 5 Béziers curves from parameters specified like in GDI+. /// </summary> public static List <XPoint> BezierCurveFromArc(double x, double y, double width, double height, double startAngle, double sweepAngle, PathStart pathStart, ref XMatrix matrix) { List <XPoint> points = new List <XPoint>(); // Normalize the angles. double α = startAngle; if (α < 0) { α = α + (1 + Math.Floor((Math.Abs(α) / 360))) * 360; } else if (α > 360) { α = α - Math.Floor(α / 360) * 360; } Debug.Assert(α >= 0 && α <= 360); double β = sweepAngle; if (β < -360) { β = -360; } else if (β > 360) { β = 360; } if (α == 0 && β < 0) { α = 360; } else if (α == 360 && β > 0) { α = 0; } // Is it possible that the arc is small starts and ends in same quadrant? bool smallAngle = Math.Abs(β) <= 90; β = α + β; if (β < 0) { β = β + (1 + Math.Floor((Math.Abs(β) / 360))) * 360; } bool clockwise = sweepAngle > 0; int startQuadrant = Quadrant(α, true, clockwise); int endQuadrant = Quadrant(β, false, clockwise); if (startQuadrant == endQuadrant && smallAngle) { AppendPartialArcQuadrant(points, x, y, width, height, α, β, pathStart, matrix); } else { int currentQuadrant = startQuadrant; bool firstLoop = true; while (true) { if (currentQuadrant == startQuadrant && firstLoop) { double ξ = currentQuadrant * 90 + (clockwise ? 90 : 0); AppendPartialArcQuadrant(points, x, y, width, height, α, ξ, pathStart, matrix); } else if (currentQuadrant == endQuadrant) { double ξ = currentQuadrant * 90 + (clockwise ? 0 : 90); AppendPartialArcQuadrant(points, x, y, width, height, ξ, β, PathStart.Ignore1st, matrix); } else { double ξ1 = currentQuadrant * 90 + (clockwise ? 0 : 90); double ξ2 = currentQuadrant * 90 + (clockwise ? 90 : 0); AppendPartialArcQuadrant(points, x, y, width, height, ξ1, ξ2, PathStart.Ignore1st, matrix); } // Don't stop immediately if arc is greater than 270 degrees. if (currentQuadrant == endQuadrant && smallAngle) { break; } smallAngle = true; if (clockwise) { currentQuadrant = currentQuadrant == 3 ? 0 : currentQuadrant + 1; } else { currentQuadrant = currentQuadrant == 0 ? 3 : currentQuadrant - 1; } firstLoop = false; } } return(points); }
/// <summary> /// Evaluates a Zero or More Path /// </summary> /// <param name="context">Evaluation Context</param> /// <returns></returns> public override BaseMultiset Evaluate(SparqlEvaluationContext context) { List <List <INode> > paths = new List <List <INode> >(); BaseMultiset initialInput = context.InputMultiset; int step = 0, prevCount = 0, skipCount = 0; String subjVar = PathStart.VariableName; String objVar = PathEnd.VariableName; bool bothTerms = (subjVar == null && objVar == null); bool reverse = false; if (subjVar == null || (context.InputMultiset.ContainsVariable(subjVar))) { // Work Forwards from the Starting Term or Bound Variable // OR if there is no Ending Term or Bound Variable work forwards regardless if (subjVar == null) { paths.Add(((NodeMatchPattern)PathStart).Node.AsEnumerable().ToList()); } else if (context.InputMultiset.ContainsVariable(subjVar)) { paths.AddRange((from s in context.InputMultiset.Sets where s[subjVar] != null select s[subjVar]).Distinct().Select(n => n.AsEnumerable().ToList())); } } else if (objVar == null || (context.InputMultiset.ContainsVariable(objVar))) { // Work Backwards from Ending Term or Bound Variable if (objVar == null) { paths.Add(((NodeMatchPattern)PathEnd).Node.AsEnumerable().ToList()); } else { paths.AddRange((from s in context.InputMultiset.Sets where s[objVar] != null select s[objVar]).Distinct().Select(n => n.AsEnumerable().ToList())); } reverse = true; } if (paths.Count == 0) { GetPathStarts(context, paths, reverse); } // Traverse the Paths do { prevCount = paths.Count; foreach (List <INode> path in paths.Skip(skipCount).ToList()) { foreach (INode nextStep in EvaluateStep(context, path, reverse)) { List <INode> newPath = new List <INode>(path); newPath.Add(nextStep); paths.Add(newPath); } } // Update Counts // skipCount is used to indicate the paths which we will ignore for the purposes of // trying to further extend since we've already done them once step++; if (paths.Count == 0) { break; } skipCount = prevCount; // Can short circuit evaluation here if both are terms and any path is acceptable if (bothTerms) { bool exit = false; foreach (List <INode> path in paths) { if (reverse) { if (PathEnd.Accepts(context, path[0]) && PathStart.Accepts(context, path[path.Count - 1])) { exit = true; break; } } else { if (PathStart.Accepts(context, path[0]) && PathEnd.Accepts(context, path[path.Count - 1])) { exit = true; break; } } } if (exit) { break; } } } while (paths.Count > prevCount || (step == 1 && paths.Count == prevCount)); if (paths.Count == 0) { // If all path starts lead nowhere then we get the Null Multiset as a result context.OutputMultiset = new NullMultiset(); } else { context.OutputMultiset = new Multiset(); // Evaluate the Paths to check that are acceptable HashSet <ISet> returnedPaths = new HashSet <ISet>(); foreach (List <INode> path in paths) { if (reverse) { if (PathEnd.Accepts(context, path[0]) && PathStart.Accepts(context, path[path.Count - 1])) { Set s = new Set(); if (!bothTerms) { if (subjVar != null) { s.Add(subjVar, path[path.Count - 1]); } if (objVar != null) { s.Add(objVar, path[0]); } } // Make sure to check for uniqueness if (returnedPaths.Contains(s)) { continue; } context.OutputMultiset.Add(s); returnedPaths.Add(s); // If both are terms can short circuit evaluation here // It is sufficient just to determine that there is one path possible if (bothTerms) { break; } } } else { if (PathStart.Accepts(context, path[0]) && PathEnd.Accepts(context, path[path.Count - 1])) { Set s = new Set(); if (!bothTerms) { if (subjVar != null) { s.Add(subjVar, path[0]); } if (objVar != null) { s.Add(objVar, path[path.Count - 1]); } } // Make sure to check for uniqueness if (returnedPaths.Contains(s)) { continue; } context.OutputMultiset.Add(s); returnedPaths.Add(s); // If both are terms can short circuit evaluation here // It is sufficient just to determine that there is one path possible if (bothTerms) { break; } } } } // Now add the zero length paths into IEnumerable <INode> nodes; if (subjVar != null) { if (objVar != null) { nodes = (from s in context.OutputMultiset.Sets where s[subjVar] != null select s[subjVar]).Concat(from s in context.OutputMultiset.Sets where s[objVar] != null select s[objVar]).Distinct(); } else { nodes = (from s in context.OutputMultiset.Sets where s[subjVar] != null select s[subjVar]).Distinct(); } } else if (objVar != null) { nodes = (from s in context.OutputMultiset.Sets where s[objVar] != null select s[objVar]).Distinct(); } else { nodes = Enumerable.Empty <INode>(); } if (bothTerms) { // If both were terms transform to an Identity/Null Multiset as appropriate if (context.OutputMultiset.IsEmpty) { context.OutputMultiset = new NullMultiset(); } else { context.OutputMultiset = new IdentityMultiset(); } } // Then union in the zero length paths context.InputMultiset = initialInput; ZeroLengthPath zeroPath = new ZeroLengthPath(PathStart, PathEnd, Path); BaseMultiset currResults = context.OutputMultiset; context.OutputMultiset = new Multiset(); BaseMultiset results = context.Evaluate(zeroPath);//zeroPath.Evaluate(context); context.OutputMultiset = currResults; foreach (ISet s in results.Sets) { if (!context.OutputMultiset.Sets.Contains(s)) { context.OutputMultiset.Add(s.Copy()); } } } context.InputMultiset = initialInput; return(context.OutputMultiset); }
/// <summary> /// Gets the String representation of the Algebra /// </summary> /// <returns></returns> public override string ToString() { return("ZeroOrMorePath(" + PathStart.ToString() + ", " + Path.ToString() + ", " + PathEnd.ToString() + ")"); }
/// <summary> /// Creates between 1 and 5 Béziers curves from parameters specified like in WPF. /// </summary> public static List<XPoint> BezierCurveFromArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArc, bool clockwise, PathStart pathStart) { // See also http://www.charlespetzold.com/blog/blog.xml from January 2, 2008: // http://www.charlespetzold.com/blog/2008/01/Mathematics-of-ArcSegment.html double δx = size.Width; double δy = size.Height; Debug.Assert(δx * δy > 0); double factor = δy / δx; bool isCounterclockwise = !clockwise; // Adjust for different radii and rotation angle. XMatrix matrix = new XMatrix(); matrix.RotateAppend(-rotationAngle); matrix.ScaleAppend(δy / δx, 1); XPoint pt1 = matrix.Transform(point1); XPoint pt2 = matrix.Transform(point2); // Get info about chord that connects both points. XPoint midPoint = new XPoint((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2); XVector vect = pt2 - pt1; double halfChord = vect.Length / 2; // Get vector from chord to center. XVector vectRotated; // (comparing two Booleans here!) if (isLargeArc == isCounterclockwise) vectRotated = new XVector(-vect.Y, vect.X); else vectRotated = new XVector(vect.Y, -vect.X); vectRotated.Normalize(); // Distance from chord to center. double centerDistance = Math.Sqrt(δy * δy - halfChord * halfChord); if (double.IsNaN(centerDistance)) centerDistance = 0; // Calculate center point. XPoint center = midPoint + centerDistance * vectRotated; // Get angles from center to the two points. double α = Math.Atan2(pt1.Y - center.Y, pt1.X - center.X); double β = Math.Atan2(pt2.Y - center.Y, pt2.X - center.X); // (another comparison of two Booleans!) if (isLargeArc == (Math.Abs(β - α) < Math.PI)) { if (α < β) α += 2 * Math.PI; else β += 2 * Math.PI; } // Invert matrix for final point calculation. matrix.Invert(); double sweepAngle = β - α; // Let the algorithm of GDI+ DrawArc to Bézier curves do the rest of the job return BezierCurveFromArc(center.X - δx * factor, center.Y - δy, 2 * δx * factor, 2 * δy, α / Calc.Deg2Rad, sweepAngle / Calc.Deg2Rad, pathStart, ref matrix); }
/// <summary> /// Appends a Bézier curve for an arc within a full quadrant. /// </summary> static void AppendPartialArcQuadrant(List<XPoint> points, double x, double y, double width, double height, double α, double β, PathStart pathStart, XMatrix matrix) { Debug.Assert(α >= 0 && α <= 360); Debug.Assert(β >= 0); if (β > 360) β = β - Math.Floor(β / 360) * 360; Debug.Assert(Math.Abs(α - β) <= 90); // Scanling factor. double δx = width / 2; double δy = height / 2; // Center of ellipse. double x0 = x + δx; double y0 = y + δy; // We have the following quarters: // | // 2 | 3 // ----+----- // 1 | 0 // | // If the angles lie in quarter 2 or 3, their values are subtracted by 180 and the // resulting curve is reflected at the center. This algorithm works as expected (simply tried out). // There may be a mathematically more elegant solution... bool reflect = false; if (α >= 180 && β >= 180) { α -= 180; β -= 180; reflect = true; } double cosα, cosβ, sinα, sinβ; if (width == height) { // Circular arc needs no correction. α = α * Calc.Deg2Rad; β = β * Calc.Deg2Rad; } else { // Elliptic arc needs the angles to be adjusted such that the scaling transformation is compensated. α = α * Calc.Deg2Rad; sinα = Math.Sin(α); if (Math.Abs(sinα) > 1E-10) α = Math.PI / 2 - Math.Atan(δy * Math.Cos(α) / (δx * sinα)); β = β * Calc.Deg2Rad; sinβ = Math.Sin(β); if (Math.Abs(sinβ) > 1E-10) β = Math.PI / 2 - Math.Atan(δy * Math.Cos(β) / (δx * sinβ)); } double κ = 4 * (1 - Math.Cos((α - β) / 2)) / (3 * Math.Sin((β - α) / 2)); sinα = Math.Sin(α); cosα = Math.Cos(α); sinβ = Math.Sin(β); cosβ = Math.Cos(β); //XPoint pt1, pt2, pt3; if (!reflect) { // Calculation for quarter 0 and 1. switch (pathStart) { case PathStart.MoveTo1st: points.Add(matrix.Transform(new XPoint(x0 + δx * cosα, y0 + δy * sinα))); break; case PathStart.LineTo1st: points.Add(matrix.Transform(new XPoint(x0 + δx * cosα, y0 + δy * sinα))); break; case PathStart.Ignore1st: break; } points.Add(matrix.Transform(new XPoint(x0 + δx * (cosα - κ * sinα), y0 + δy * (sinα + κ * cosα)))); points.Add(matrix.Transform(new XPoint(x0 + δx * (cosβ + κ * sinβ), y0 + δy * (sinβ - κ * cosβ)))); points.Add(matrix.Transform(new XPoint(x0 + δx * cosβ, y0 + δy * sinβ))); } else { // Calculation for quarter 2 and 3. switch (pathStart) { case PathStart.MoveTo1st: points.Add(matrix.Transform(new XPoint(x0 - δx * cosα, y0 - δy * sinα))); break; case PathStart.LineTo1st: points.Add(matrix.Transform(new XPoint(x0 - δx * cosα, y0 - δy * sinα))); break; case PathStart.Ignore1st: break; } points.Add(matrix.Transform(new XPoint(x0 - δx * (cosα - κ * sinα), y0 - δy * (sinα + κ * cosα)))); points.Add(matrix.Transform(new XPoint(x0 - δx * (cosβ + κ * sinβ), y0 - δy * (sinβ - κ * cosβ)))); points.Add(matrix.Transform(new XPoint(x0 - δx * cosβ, y0 - δy * sinβ))); } }
/// <summary> /// Creates between 1 and 5 Béziers curves from parameters specified like in GDI+. /// </summary> public static List<XPoint> BezierCurveFromArc(double x, double y, double width, double height, double startAngle, double sweepAngle, PathStart pathStart, ref XMatrix matrix) { List<XPoint> points = new List<XPoint>(); // Normalize the angles. double α = startAngle; if (α < 0) α = α + (1 + Math.Floor((Math.Abs(α) / 360))) * 360; else if (α > 360) α = α - Math.Floor(α / 360) * 360; Debug.Assert(α >= 0 && α <= 360); double β = sweepAngle; if (β < -360) β = -360; else if (β > 360) β = 360; if (α == 0 && β < 0) α = 360; else if (α == 360 && β > 0) α = 0; // Is it possible that the arc is small starts and ends in same quadrant? bool smallAngle = Math.Abs(β) <= 90; β = α + β; if (β < 0) β = β + (1 + Math.Floor((Math.Abs(β) / 360))) * 360; bool clockwise = sweepAngle > 0; int startQuadrant = Quadrant(α, true, clockwise); int endQuadrant = Quadrant(β, false, clockwise); if (startQuadrant == endQuadrant && smallAngle) AppendPartialArcQuadrant(points, x, y, width, height, α, β, pathStart, matrix); else { int currentQuadrant = startQuadrant; bool firstLoop = true; do { if (currentQuadrant == startQuadrant && firstLoop) { double ξ = currentQuadrant * 90 + (clockwise ? 90 : 0); AppendPartialArcQuadrant(points, x, y, width, height, α, ξ, pathStart, matrix); } else if (currentQuadrant == endQuadrant) { double ξ = currentQuadrant * 90 + (clockwise ? 0 : 90); AppendPartialArcQuadrant(points, x, y, width, height, ξ, β, PathStart.Ignore1st, matrix); } else { double ξ1 = currentQuadrant * 90 + (clockwise ? 0 : 90); double ξ2 = currentQuadrant * 90 + (clockwise ? 90 : 0); AppendPartialArcQuadrant(points, x, y, width, height, ξ1, ξ2, PathStart.Ignore1st, matrix); } // Don't stop immediately if arc is greater than 270 degrees. if (currentQuadrant == endQuadrant && smallAngle) break; smallAngle = true; if (clockwise) currentQuadrant = currentQuadrant == 3 ? 0 : currentQuadrant + 1; else currentQuadrant = currentQuadrant == 0 ? 3 : currentQuadrant - 1; firstLoop = false; } while (true); } return points; }
void AppendPartialArc(System.Windows.Point point1, System.Windows.Point point2, double rotationAngle, System.Windows.Size size, bool isLargeArc, System.Windows.Media.SweepDirection sweepDirection, PathStart pathStart) { #if true //AppendPartialArc(currentPoint, seg.Point, seg.RotationAngle, seg.Size, seg.IsLargeArc, seg.SweepDirection, PathStart.Ignore1st); int pieces; PointCollection points = GeometryHelper.ArcToBezier(point1.X, point1.Y, size.Width, size.Height, rotationAngle, isLargeArc, sweepDirection == SweepDirection.Clockwise, point2.X, point2.Y, out pieces); int count = points.Count; int start = count % 3 == 1 ? 1 : 0; if (start == 1) AppendFormat("{0:0.####} {1:0.####} m\n", points[0].X, points[0].Y); for (int idx = start; idx < count; idx += 3) AppendFormat("{0:0.####} {1:0.####} {2:0.####} {3:0.####} {4:0.####} {5:0.####} c\n", points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y); #else List<XPoint> points = GeometryHelper.BezierCurveFromArc((XPoint)point1, (XPoint)point2, rotationAngle, (XSize)size, isLargeArc, sweepDirection == SweepDirection.Clockwise, pathStart); int count = points.Count; int start = count % 3 == 1 ? 1 : 0; if (start == 1) AppendFormat("{0:0.####} {1:0.####} m\n", points[0].X, points[0].Y); for (int idx = start; idx < count; idx += 3) AppendFormat("{0:0.####} {1:0.####} {2:0.####} {3:0.####} {4:0.####} {5:0.####} c\n", points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y); #endif }
// Use this for initialization void Start() { // get the path manager WaveManager = GameObject.Find("PathPoint (0)").GetComponent <PathStart>(); }
/// <summary> /// Evaluates a Zero Length Path. /// </summary> /// <param name="context">Evaluation Context.</param> /// <returns></returns> public override BaseMultiset Evaluate(SparqlEvaluationContext context) { if (AreBothTerms()) { if (AreSameTerms()) { return(new IdentityMultiset()); } else { return(new NullMultiset()); } } String subjVar = PathStart.VariableName; String objVar = PathEnd.VariableName; context.OutputMultiset = new Multiset(); // Determine the Triples to which this applies if (subjVar != null) { // Subject is a Variable if (context.InputMultiset.ContainsVariable(subjVar)) { // Subject is Bound if (objVar != null) { // Object is a Variable if (context.InputMultiset.ContainsVariable(objVar)) { // Both Subject and Object are Bound foreach (ISet s in context.InputMultiset.Sets.Where(x => x[subjVar] != null && x[objVar] != null && PathStart.Accepts(context, x[subjVar]) && PathEnd.Accepts(context, x[objVar]))) { ISet x = new Set(); x.Add(subjVar, x[subjVar]); context.OutputMultiset.Add(x); x = new Set(); x.Add(objVar, x[objVar]); context.OutputMultiset.Add(x); } } else { // Subject is bound but Object is Unbound foreach (ISet s in context.InputMultiset.Sets.Where(x => x[subjVar] != null && PathStart.Accepts(context, x[subjVar]))) { ISet x = s.Copy(); x.Add(objVar, x[subjVar]); context.OutputMultiset.Add(x); } } } else { // Object is a Term // Preseve sets where the Object Term is equal to the currently bound Subject INode objTerm = ((NodeMatchPattern)PathEnd).Node; foreach (ISet s in context.InputMultiset.Sets) { INode temp = s[subjVar]; if (temp != null && temp.Equals(objTerm)) { context.OutputMultiset.Add(s.Copy()); } } } } else { // Subject is Unbound if (objVar != null) { // Object is a Variable if (context.InputMultiset.ContainsVariable(objVar)) { // Object is Bound but Subject is unbound foreach (ISet s in context.InputMultiset.Sets.Where(x => x[objVar] != null && PathEnd.Accepts(context, x[objVar]))) { ISet x = s.Copy(); x.Add(subjVar, x[objVar]); context.OutputMultiset.Add(x); } } else { // Subject and Object are Unbound HashSet <INode> nodes = new HashSet <INode>(); foreach (Triple t in context.Data.Triples) { nodes.Add(t.Subject); nodes.Add(t.Object); } foreach (INode n in nodes) { Set s = new Set(); s.Add(subjVar, n); s.Add(objVar, n); context.OutputMultiset.Add(s); } } } else { // Object is a Term // Create a single set with the Variable bound to the Object Term Set s = new Set(); s.Add(subjVar, ((NodeMatchPattern)PathEnd).Node); context.OutputMultiset.Add(s); } } } else if (objVar != null) { // Subject is a Term but Object is a Variable if (context.InputMultiset.ContainsVariable(objVar)) { // Object is Bound // Preseve sets where the Subject Term is equal to the currently bound Object INode subjTerm = ((NodeMatchPattern)PathStart).Node; foreach (ISet s in context.InputMultiset.Sets) { INode temp = s[objVar]; if (temp != null && temp.Equals(subjTerm)) { context.OutputMultiset.Add(s.Copy()); } } } else { // Object is Unbound // Create a single set with the Variable bound to the Suject Term Set s = new Set(); s.Add(objVar, ((NodeMatchPattern)PathStart).Node); context.OutputMultiset.Add(s); } } else { // Should already have dealt with this earlier (the AreBothTerms() and AreSameTerms() branch) throw new RdfQueryException("Reached unexpected point of ZeroLengthPath evaluation"); } return(context.OutputMultiset); }
// Use this for initialization void Start() { // set the model as a random model in the inputed list GetComponent <MeshFilter>().mesh = models[Random.Range(0, models.Count)]; WaveManager = GameObject.Find("PathPoint (0)").GetComponent <PathStart>(); }
void AppendPartialArc(SysPoint point1, SysPoint point2, double rotationAngle, SysSize size, bool isLargeArc, SweepDirection sweepDirection, PathStart pathStart) { const string format = Config.SignificantFigures4; Debug.Assert(pathStart == PathStart.Ignore1st); int pieces; PointCollection points = GeometryHelper.ArcToBezier(point1.X, point1.Y, size.Width, size.Height, rotationAngle, isLargeArc, sweepDirection == SweepDirection.Clockwise, point2.X, point2.Y, out pieces); int count = points.Count; int start = count % 3 == 1 ? 1 : 0; if (start == 1) AppendFormatPoint("{0:" + format + "} {1:" + format + "} m\n", points[0].X, points[0].Y); for (int idx = start; idx < count; idx += 3) AppendFormat3Points("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} c\n", points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y); }
void AppendPartialArc(System.Windows.Point point1, System.Windows.Point point2, double rotationAngle, System.Windows.Size size, bool isLargeArc, System.Windows.Media.SweepDirection sweepDirection, PathStart pathStart) { List<XPoint> points = GeometryHelper.BezierCurveFromArc((XPoint)point1, (XPoint)point2, rotationAngle, (XSize)size, isLargeArc, sweepDirection == SweepDirection.Clockwise, pathStart); int count = points.Count; int start = count % 3 == 1 ? 1 : 0; if (start == 1) AppendFormat("{0:0.####} {1:0.####} m\n", points[0].X, points[0].Y); for (int idx = start; idx < count; idx += 3) AppendFormat("{0:0.####} {1:0.####} {2:0.####} {3:0.####} {4:0.####} {5:0.####} c\n", points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y); }
public void OnGUI() { #region UIRendering //load the gui skin GUI.skin = skin; int ResolutionWidth = Screen.width; int ResolutionHeight = Screen.height; PathStart WaveManager = GameObject.Find("PathPoint (0)").GetComponent <PathStart>(); //draw the tower selection grid int boxNumber = ((Screen.height - 315) / 100) * 2; List <GUIContent> TowerSelectionGrid = new List <GUIContent>(); for (int i = towerPage * boxNumber; i < Towers.Count && i < boxNumber + towerPage * boxNumber; i++) { TowerSelectionGrid.Add(new GUIContent(Towers[i].Name + "\n<size=16>cost:" + Towers[i].TowerObject.GetComponent <Tower>().getCost() + "</size>", Towers[i].GuiTexture == null ? NoTowerImage : Towers[i].GuiTexture)); } for (int i = TowerSelectionGrid.Count; i < boxNumber; i++) { TowerSelectionGrid.Add(new GUIContent("")); } //draw the box for money and health; GUI.Box(new Rect(ResolutionWidth - 200, 0, 200, 100), new GUIContent("Health:" + GameObject.FindGameObjectWithTag("ProtectedObject").GetComponent <ProtectedObject>().health + "\n Money:" + money + "\n Score:" + PathManager.Score)); selectorGrid = GUI.SelectionGrid(new Rect(ResolutionWidth - 200, 105, 200, ResolutionHeight - 315), selectorGrid, TowerSelectionGrid.ToArray(), 2); //draw the next button for tower page if (towerPage == TowerPageMax) { GUI.Box(new Rect(ResolutionWidth - 98, ResolutionHeight - 205, 98, 100), new GUIContent("<color=#808080ff>next</color>")); } else if (GUI.Button(new Rect(ResolutionWidth - 98, ResolutionHeight - 205, 98, 100), new GUIContent("next"))) { towerPage += 1; } //draw the previous button for tower page if (towerPage == 0) { GUI.Box(new Rect(ResolutionWidth - 200, ResolutionHeight - 205, 98, 100), new GUIContent("<color=#808080ff>Previous</color>")); } else if (GUI.Button(new Rect(ResolutionWidth - 200, ResolutionHeight - 205, 98, 100), new GUIContent("Previous"))) { towerPage -= 1; } //check if the player can go to the next wave if (WaveManager.CanNextWave) { //check if the level is finished if (WaveManager.isFinalWave) { // create finished texture GUIStyle OuterBox = new GUIStyle(GUI.skin.box); Texture2D texture = new Texture2D(1, 1); texture.SetPixel(0, 0, Color.white); texture.Apply(); OuterBox.normal.background = texture; //display finished message and the button to end the game GUI.Label(new Rect(ResolutionWidth / 2 - 500, ResolutionHeight / 2 - 100, 500, 150), "", OuterBox); GUI.Label(new Rect(ResolutionWidth / 2 - 500, ResolutionHeight / 2 - 100, 500, 150), new GUIContent("<size=128><color=Black>Great Job</color></size>")); if (GUI.Button(new Rect(ResolutionWidth - 200, ResolutionHeight - 100, 200, 100), new GUIContent("Exit to Main Menu"))) { PlayerPrefs.SetInt("level:" + UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex, (int)PathManager.Score); UnityEngine.SceneManagement.SceneManager.LoadScene(0); } } //otherwise show a button to go to next level else if (GUI.Button(new Rect(ResolutionWidth - 200, ResolutionHeight - 100, 200, 100), new GUIContent("Next Wave" + WaveManager.TimeToNextWave))) { WaveManager.nextWave(); } } else { GUI.Box(new Rect(ResolutionWidth - 200, ResolutionHeight - 100, 200, 100), new GUIContent("Wave In Progress")); } //show options button if (GUI.Button(new Rect(8, ResolutionHeight - 40, 32, 32), GearSymbol)) { Options = !Options; } //show music button if (GUI.Button(new Rect(48, ResolutionHeight - 40, 32, 32), music ? MusicSymbol : NoMusicSymbol)) { music = !music; PlayerPrefs.SetInt("music", music ? 1 : 0); AudioListener.volume = music ? 1 : 0; } #endregion #region UIControls //move camera around if (Input.GetAxis("Mouse ScrollWheel") < 0 || Input.GetAxis("Mouse ScrollWheel") > 0 && Camera.main != null) { Camera.main.orthographicSize = Mathf.Max(Mathf.Min(-8 * scrollSpeed * Input.GetAxis("Mouse ScrollWheel") + Camera.main.orthographicSize, 50), 5); } //if user presses e open the options menu if (Input.GetKeyDown(KeyCode.Escape) & Time.unscaledTime - buttonTime > .5f) { Options = !Options; buttonTime = Time.unscaledTime; } //show options menu if (Options) { //draw options box Rect OptionsBox = new Rect((ResolutionWidth - 200) / 2, (ResolutionHeight - 132) / 2, 200, 152); GUI.Box(OptionsBox, ""); //draw the quit buttons if (GUI.Button(new Rect(OptionsBox.xMin + (OptionsBox.width - 150) / 2, OptionsBox.yMin + 16, 150, 50), "Quit To Windows")) { Application.Quit(); } if (GUI.Button(new Rect(OptionsBox.xMin + (OptionsBox.width - 150) / 2, OptionsBox.yMin + 66, 150, 50), "Quit To Main Menu")) { UnityEngine.SceneManagement.SceneManager.LoadScene(0); } hardness = !GUI.Toggle(new Rect(OptionsBox.xMin + (OptionsBox.width - 150) / 2, OptionsBox.yMin + 116, 150, 50), hardness, "Hard Mode"); PlayerPrefs.SetInt("Hardness", hardness?1:0); } //show the diologue for selling towers else if (ThingToSell != null) { //convert 3d point to 2d screen position Vector3 screenPosition = Camera.main.WorldToScreenPoint(ThingToSell.transform.position + Vector3.up); // gets screen position.\ screenPosition.y = Screen.height - (screenPosition.y + 1); // inverts y Rect rect = new Rect(screenPosition.x - 50, screenPosition.y - 12, 100, 60); // makes a rect centered at the player ( 100x24 ) GUI.Box(rect, "", GUI.skin.box); //shjow sell button if (GUI.Button(new Rect(rect.xMin + 4, rect.yMin + 4, 92, 24), "Sell", GUI.skin.button)) { money += hardness? ThingToSell.getCost() / 2:0; Destroy(ThingToSell.gameObject); } //show cancel button else if (GUI.Button(new Rect(rect.xMin + 4, rect.yMin + 28, 92, 24), "Cancel", GUI.skin.button)) { ThingToSell = null; } } //check for user mouse click else if (Input.GetMouseButtonDown(0)) { if (justclicked == false) { //check iuf the user clicked on a tile RaycastHit hit; Ray clicked3D = Camera.main.ScreenPointToRay(Input.mousePosition); Physics.Raycast(clicked3D, out hit, 100000f); if (hit.transform != null && hit.transform.gameObject.tag == "BuildTile") { //if clicked on a tile create tower BuildTile Tile = hit.transform.gameObject.GetComponent <BuildTile>(); if (Tile.Tower == null) { if (money >= Towers[selectorGrid + towerPage * boxNumber].TowerObject.GetComponent <Tower>().getCost()) { money -= Towers[selectorGrid + towerPage * boxNumber].TowerObject.GetComponent <Tower>().getCost(); Tile.Tower = (Instantiate(Towers[selectorGrid + towerPage * boxNumber].TowerObject, hit.transform.position + new Vector3(0, .75f, 0), new Quaternion()) as GameObject); } } } //if user clicked on tower show sell diologue else if (hit.transform != null && hit.transform.gameObject.tag == "Tower") { ThingToSell = hit.transform.gameObject.GetComponent <Tower>(); } } justclicked = !justclicked; } //move camera based on arrow keys and wasd MousePositionMoving = new Vector3(0, 0, 0); if (Input.GetMouseButton(2) == true) { MousePositionMoving = new Vector3(MouseLastX - Input.mousePosition.x, MouseLastY - Input.mousePosition.y, 0) * (Camera.main.orthographicSize / 160); } MouseLastX = (int)Input.mousePosition.x; MouseLastY = (int)Input.mousePosition.y; Camera.main.transform.Translate(new Vector3(Input.GetAxis("Horizontal") * cameraMouseSpeed, Input.GetAxis("Vertical") * cameraMouseSpeed, 0) + MousePositionMoving); //if user presses e turn the camera if (Input.GetKey(KeyCode.E)) { //Find point from camera and angle to y = zero point float angle; Vector3 axis; this.transform.rotation.ToAngleAxis(out angle, out axis); Vector3 LookDir = this.transform.rotation * new Vector3(0, 0, 1); Vector2 RatioDir = new Vector2(LookDir.x, LookDir.z); RatioDir.Normalize(); //rotate around this point Vector3 endPoint = new Vector3(transform.position.x + RatioDir.x * transform.position.y, 0, transform.position.z + RatioDir.y * transform.position.y); this.transform.RotateAround(endPoint, Vector3.up, scrollSpeed / -3); } //if user presses e turn the camera if (Input.GetKey(KeyCode.Q)) { //Find point from camera and angle to y = zero point float angle; Vector3 axis; this.transform.rotation.ToAngleAxis(out angle, out axis); Vector3 LookDir = this.transform.rotation * new Vector3(0, 0, 1); Vector2 RatioDir = new Vector2(LookDir.x, LookDir.z); RatioDir.Normalize(); //rotate around this point Vector3 endPoint = new Vector3(transform.position.x + RatioDir.x * transform.position.y, 0, transform.position.z + RatioDir.y * transform.position.y); this.transform.RotateAround(endPoint, Vector3.up, scrollSpeed / 3); } #endregion }