/// <summary> /// Creates a new rectangle shaped sub-path. /// </summary> public static void Rect(this Nvg nvg, Rectangle <float> rect) { InstructionQueue queue = nvg.instructionQueue; queue.AddMoveTo(rect.Origin); queue.AddLineTo(new(rect.Origin.X, rect.Max.Y)); queue.AddLineTo(rect.Max); queue.AddLineTo(new(rect.Max.X, rect.Origin.Y)); queue.AddClose(); }
/// <summary> /// Creates new circle arc shaped sub-path. /// The arc is drawn from angle a0 to a1. /// </summary> /// <param name="c">The arc center.</param> /// <param name="r">The arc radius.</param> /// <param name="dir">The direction the arc is swept in.</param> public static void Arc(this Nvg nvg, Vector2D <float> c, float r, float a0, float a1, Winding dir) { Vector2D <float> pPos = default; Vector2D <float> pTan = default; InstructionQueue queue = nvg.instructionQueue; bool line = queue.Count > 0; float da = a1 - a0; if (dir == Winding.Cw) { if (MathF.Abs(da) >= MathF.PI * 2.0f) { da = MathF.PI * 2.0f; } else { while (da < 0.0f) { da += MathF.PI * 2.0f; } } } else { if (MathF.Abs(da) >= MathF.PI * 2.0f) { da = -MathF.PI * 2.0f; } else { while (da > 0.0f) { da -= MathF.PI * 2.0f; } } } int ndivs = Math.Max(1, Math.Min((int)(MathF.Abs(da) / (MathF.PI * 0.5f) + 0.5f), 5)); float hda = (da / (float)ndivs) / 2.0f; float kappa = MathF.Abs(4.0f / 3.0f * (1.0f - MathF.Cos(hda)) / MathF.Sin(hda)); if (dir == Winding.Ccw) { kappa *= -1.0f; } for (int i = 0; i <= ndivs; i++) { float alpha = a0 + da * ((float)i / (float)ndivs); Vector2D <float> d = new(MathF.Cos(alpha), MathF.Sin(alpha)); Vector2D <float> pos = new(c.X + d.X * r, c.Y + d.Y * r); Vector2D <float> tan = new(-d.Y * r * kappa, d.X *r *kappa); if (i == 0) { if (line) { queue.AddLineTo(pos); } else { queue.AddMoveTo(pos); } } else { queue.AddBezierTo(pPos + pTan, pos - tan, pos); } pPos = pos; pTan = tan; } }