c# - Given bounding rectangle, starting angle, and sweep angle, how to determine points of the arc endpoints -


given bounding rectangle, starting angle , sweep angle, how determine points of each end of arc?

private void mypaint(object sender, painteventargs e)    {       graphics g = e.graphics;        rectangle rc = new rectangle(242, 299, 200, 300);       pen penred = new pen(color.red, 1);        g.drawarc(penred, rc, 18, -108);        // todo - determine point of each end of arc       // point pt1 = ???    // point pt2 = ??? } 

enter image description here

using equation of ellipse excellent mathematics answer can calculate start , end points of ellipse, given start angle , sweep.

first, need center of bounding box, know how shift coordinates. that's simply

rectangle rc = new rectangle(242, 299, 200, 300);  int cx = (rc.left + rc.right) / 2; int cy = (rc.bottom + rc.top) / 2;  // debugging purposes, let's mark point. g.fillrectangle(brushes.yellow, rectangle.fromltrb(cx - 3, cy - 3, cx + 3, cy + 3)); 

we need convert angles degrees radians, , change clockwise angle counter-clockwise angle so:

double mintheta = (math.pi / 180) * (360 - start); double maxtheta = (math.pi / 180) * (360 - (start + sweep)); 

we'll define 2 helper functions, first normalize angle (map arbitrary angles range 0-360) , second adjust calculated (x, y) coordinates correct quadrant. (given positive y down on form)

public double normalizeangle(double angle) {     while (angle >= 360) angle -= 360;     while (angle < 0) angle += 360;     return angle; } public void adjustcoordinatesforangle(double angle, ref double x, ref double y) {     if (angle > 0 && angle <= 90)     {         x *= 1;         y *= 1;     }     else if (angle >= 90 && angle < 180)     {         x *= -1;         y *= 1;     }     else if (angle >= 180 && angle < 270)     {         x *= -1;         y *= -1;     }     else if (angle >= 270 && angle < 360)     {         x *= 1;         y *= -1;     } } 

we have enough information calculate start , end points.

double mintheta = (math.pi / 180) * (360 - start); double maxtheta = (math.pi / 180) * (360 - (start + sweep));  double = width / 2.0; double b = height / 2.0;  double denom = math.pow(a, 2) * math.pow(math.tan(mintheta), 2); denom = denom / math.pow(b, 2); denom = math.sqrt(denom + 1);  double x = math.abs(a / denom); double y = math.abs((a * math.tan(mintheta)) / denom);  start = normalizeangle(start); this.adjustcoordinatesforangle(start, ref x, ref y); 

those coordinates relative bounding box's center, offset using center point calculated above:

x += cx; y += cy; 

we can draw point:

g.fillrectangle(brushes.purple, new rectangle((int)x - 3, (int)y - 3, 6, 6)); 

all paint function looks this:

private void mypaint(object sender, painteventargs e) {     double start = 18;     double sweep = -108;      graphics g = e.graphics;      g.clear(color.black);      rectangle rc = new rectangle(200, 10, 200, 300);      int cx = (rc.left + rc.right) / 2;     int cy = (rc.bottom + rc.top) / 2;      g.fillrectangle(brushes.yellow, rectangle.fromltrb(cx - 3, cy - 3, cx + 3, cy + 3));      int width = rc.width;     int height = rc.height;      if (start >= 360) start -= 360;      double mintheta = (math.pi / 180) * (360 - start);     double maxtheta = (math.pi / 180) * (360 - (start + sweep));      double = width / 2.0;     double b = height / 2.0;      double denom = math.pow(a, 2) * math.pow(math.tan(mintheta), 2);     denom = denom / math.pow(b, 2);     denom = math.sqrt(denom + 1);      double x = math.abs(a / denom);     double y = math.abs((a * math.tan(mintheta)) / denom);      start = normalizeangle(start);     this.adjustcoordinatesforangle(start, ref x, ref y);      x += cx;     y += cy;      g.fillrectangle(brushes.purple, new rectangle((int)x - 3, (int)y - 3, 6, 6));      denom = math.pow(a, 2) * math.pow(math.tan(maxtheta), 2);     denom = denom / math.pow(b, 2);     denom = math.sqrt(denom + 1);      x = math.abs(a / denom);     y = math.abs((a * math.tan(maxtheta)) / denom);      double endangle = (start + sweep);     endangle = normalizeangle(endangle);     this.adjustcoordinatesforangle(endangle, ref x, ref y);      x += cx;     y += cy;      g.fillrectangle(brushes.blue, new rectangle((int)x - 3, (int)y - 3, 6, 6));       pen penred = new pen(color.red, 1);     g.drawrectangle(pens.green, rc);     g.drawarc(penred, rc, (float)start, (float)sweep); } 

i painted window background black make boxes , lines stand out better, , left in additional drawing elements, easier see what's happening in calculations above.

placing code form, , associating form's paint event produces result:

final result

one final note, due rounding, start , end points may off pixel or two. if want more accuracy, you'd have draw arc yourself.


Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -