{"id":119,"date":"2009-02-02T20:28:20","date_gmt":"2009-02-02T19:28:20","guid":{"rendered":"http:\/\/floris.briolas.nl\/floris\/?p=119"},"modified":"2009-02-03T10:48:14","modified_gmt":"2009-02-03T09:48:14","slug":"arcto-arcsegment-like-graphicspathaddarc","status":"publish","type":"post","link":"https:\/\/floris.briolas.nl\/floris\/2009\/02\/arcto-arcsegment-like-graphicspathaddarc\/","title":{"rendered":"ArcTo \/ ArcSegment like GraphicsPath.AddArc"},"content":{"rendered":"<p>This article gives a simpler interface (facade) to use the ArcTo Method&#8230; Providing a GraphicsPath AddArc like method.<\/p>\n<pre name=\"code\" class=\"c#\">public static GeometryDrawing GetArc(Rect rect, Angle start, Angle sweep){}<\/pre>\n<p>Today I implemented an adapter for GDI+ and WPF to draw similar objects. Simple ons like line, rectangle, ellipse,.. but I kinda struggled with arc??!!<\/p>\n<table style=\"height: 184px;\" border=\"0\" width=\"305\">\n<tbody>\n<tr>\n<td>\n<pre class=\"c#\" name=\"code\">public abstract void ArcTo(\r\n\tPoint point,\r\n\tSize size,\r\n\tdouble rotationAngle,\r\n\tbool isLargeArc,\r\n\tSweepDirection sweepDirection,\r\n\tbool isStroked,\r\n\tbool isSmoothJoin\r\n)<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This is an Api that has way to much parameters if you ask me. All I need (and want) was a api like the AddArc on the GDI+ GraphicsPath which looks like :<\/p>\n<table style=\"height: 113px;\" border=\"0\" width=\"217\">\n<tbody>\n<tr>\n<td>\n<pre name=\"code\" class=\"c#\">public void AddArc(\r\n\tRectangleF rect,\r\n\tfloat startAngle,\r\n\tfloat sweepAngle\r\n)<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Which is all I need anyway.<\/p>\n<p>In My Code I&#8217;m using the ArcTo method on a StreamGeometryContext instance (ArcSegment has a similair api so I&#8217;mmentioning it).  First you have to move to the first point (which is done by calling BeginFigure) then you have to add a second point. Next argument <strong>Size<\/strong> has an interesting description on the MSDN documentation:<\/p>\n<blockquote><p>The width and height of an oval whose perimeter is used to draw the angle. If the oval is very rounded in all directions, the arc will be rounded, if it is nearly flat, so will the arc. For example, a very large width and height would represent a very large oval, which would give a slight curvature for the angle.<\/p><\/blockquote>\n<p>Ehh.. right.. how about just saying <strong>radius<\/strong>?<\/p>\n<p>The next argument, rotationangle, can be done with a Matrix transform (rotate),.. so why it it there?<\/p>\n<p>well the others make sense&#8230;<\/p>\n<p>Well here is my facade to the ArcTo:<\/p>\n<pre name=\"code\" class=\"c#\">public static GeometryDrawing GetArc(Rect rect, Angle start, Angle sweep)<\/pre>\n<p>the way i like it,.. nice and simple.<\/p>\n<pre name=\"code\" class=\"c#\">public static GeometryDrawing GetArc(Rect rect, Angle start, Angle sweep)\r\n        {\r\n            GeometryDrawing ret = new GeometryDrawing();\r\n            StreamGeometry geo = new StreamGeometry();\r\n\r\n            \/\/Set correct parameters\r\n            SweepDirection sweepDir = sweep.Degrees &lt; 0 ? SweepDirection.Counterclockwise : SweepDirection.Clockwise;\r\n            bool isLargeArc = Math.Abs(sweep.Degrees) &gt; 180;\r\n\r\n            double cx = rect.Width \/ 2;\r\n            double cy = rect.Height \/ 2;\r\n            \/\/Calculate start point\r\n            double x1 = rect.X + cx + (Math.Cos(start.Radians) * cx);\r\n            double y1 = rect.Y + cy + (Math.Sin(start.Radians) * cy);\r\n            \/\/Calculate end point\r\n            double x2 = rect.X + cx + (Math.Cos(start.Radians + sweep.Radians) * cx);\r\n            double y2 = rect.Y + cy + (Math.Sin(start.Radians + sweep.Radians) * cy);\r\n\r\n            using (StreamGeometryContext ctx = geo.Open())\r\n            {\r\n                ctx.BeginFigure(new Point(x1, y1), false, false);\r\n                ctx.ArcTo(new Point(x2, y2), new Size(cx,cy), 0, isLargeArc, sweepDir, true, false);\r\n            }\r\n\r\n            ret.Geometry = geo;\r\n            return ret;\r\n        }<\/pre>\n<p><strong>!NOTE!<\/strong> The Angle class is just a simple converter form degrees to radians Nothing to worry about&#8230;.<\/p>\n<p><a href=\"http:\/\/floris.briolas.nl\/floris\/downloads\/DrawArcInRect.zip\">Here you can download a sample solution<\/a> to get the demo working.<\/p>\n<p>Or use this Extention Method in a static class..<\/p>\n<pre  name=\"code\" class=\"c#\">\r\npublic static void AddArc(this StreamGeometryContext ctx, Rect rect, double startRad, double sweepRad)\r\n{\r\nSweepDirection sweepDir = sweepRad < 0 ? SweepDirection.Counterclockwise : SweepDirection.Clockwise;\r\nbool isLargeArc = Math.Abs(sweepRad) > Math.PI;\r\ndouble cx = rect.Width \/ 2;\r\ndouble cy = rect.Height \/ 2;\r\ndouble x1 = rect.X + cx + (Math.Cos(startRad) * cx);\r\ndouble y1 = rect.Y + cy + (Math.Sin(startRad) * cy);\r\ndouble x2 = rect.X + cx + (Math.Cos(startRad + sweepRad) * cx);\r\ndouble y2 = rect.Y + cy + (Math.Sin(startRad + sweepRad) * cy);\r\nctx.BeginFigure(new Point(x1, y1), false, false);\r\nctx.ArcTo(new Point(x2, y2), new Size(cx, cy), 0, isLargeArc, sweepDir, true, false);\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This article gives a simpler interface (facade) to use the ArcTo Method&#8230; Providing a GraphicsPath AddArc like method. public static GeometryDrawing GetArc(Rect rect, Angle start, Angle sweep){} Today I implemented an adapter for GDI+ and WPF to draw similar objects. Simple ons like line, rectangle, ellipse,.. but I kinda struggled with arc??!! public abstract void [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_newsletter_tier_id":0,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[3,11],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p61yPs-1V","_links":{"self":[{"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/posts\/119"}],"collection":[{"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/comments?post=119"}],"version-history":[{"count":19,"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/posts\/119\/revisions"}],"predecessor-version":[{"id":140,"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/posts\/119\/revisions\/140"}],"wp:attachment":[{"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/media?parent=119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/categories?post=119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/floris.briolas.nl\/floris\/wp-json\/wp\/v2\/tags?post=119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}