<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
    <title></title>
  </head>
  <body bgcolor="#ffffff" text="#000000">
    Hi Hilaire,<br>
    <br>
    On 5/4/2021 4:18 PM, Hilaire Fernandes via Cuis-dev wrote:
    <blockquote cite="mid:cf40f271-0724-c576-7588-538848737548@drgeo.eu"
      type="cite">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <p>Hi Juan,</p>
      <p>In DrGeo, the user can define an arc passing though three
        points (there is other way). With Vector Graphics primitive,
        there is this largeFlag attribute, depending on its value and
        the position of the three user defined points, the arc will do
        or not as expected.</p>
      <p>Bellow the arc does not do as expected, when largeFlag is
        false. if I toggle largeFlag to true, then the arc goes through
        the three points.</p>
      <p><img moz-do-not-send="false"
          src="cid:part1.05040207.06060500@jvuletich.org" alt="The arc
          does not pass by the third point" height="159" width="157"> <br>
      </p>
      <p>However it will not work the other way, when the second point
        is moved close to the other points. I don't understand how
        should the largeFlag attribute be set.</p>
      <p>The DrGeo's arc model knows about its center, radius, starting
        angle, and its oriented angle. Its polymoprhic pointAt: method
        gives the coordinates of any point on its line, with curvilinear
        abscissa between 0 and 1.<br>
      </p>
      <pre>drawOn: canvas
    | start end r orientation |
    start _ self drawable worldToMorph: (mathItem pointAt: 0).
    end  _ self drawable worldToMorph: (mathItem pointAt: 1).
    r _ self drawable worldToPixel: mathItem radius.
    orientation _ mathItem length negative.
    canvas strokeWidth: borderWidth color: borderColor do: [
        canvas moveToX: start x y: start y;
        arcToX: end x y: end y rx: r  ry: r angleOfXAxis: 0 largeFlag: false sweepFlag: orientation]
</pre>
      <p><br>
      </p>
      <pre class="moz-signature" cols="72">-- 
GNU Dr. Geo
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://drgeo.eu">http://drgeo.eu</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://blog.drgeo.eu">http://blog.drgeo.eu</a></pre>
    </blockquote>
    <br>
    The arc implementation follows
    <a class="moz-txt-link-freetext" href="https://www.w3.org/TR/SVG/implnote.html">https://www.w3.org/TR/SVG/implnote.html</a> . With the start and end
    points and a radius, and without knowing the center, or the third
    point, in general there are two possible whole circles, and four
    possible arcs. Of each of the two whole circles we could chose to
    draw the smaller or the larger arc. That's what the large flag is
    for.<br>
    <br>
    I know. This is not clear at all. But it is what the SVG stadard
    does, which I chose to follow it. Maybe a code example will help.
    Note that negating the flags will draw the other alternative arcs
    honoring start, end and radius, but not middle point.<br>
    The whole example, to play in a workspace, is:<br>
    <br>
    x1 _ 400. y1 _ 300.<br>
    x3 _ 600. y3 _ 700.<br>
    "various examples of mid point"<br>
    x2 _ 900. y2 _ 450.<br>
    x2 _ 900. y2 _ 1450.<br>
    x2 _ 300. y2 _ 1450.<br>
    x2 _ 300. y2 _ 450.<br>
    x2 _ 300. y2 _ 650.<br>
    x2 _ 300. y2 _ 950.<br>
    x2 _ 1300. y2 _ 950.<br>
    x2 _ 1300. y2 _ 350.<br>
    x2 _ 600. y2 _ 350.<br>
    x2 _ 600. y2 _ 150.<br>
    "Shamesly copied from
<a class="moz-txt-link-freetext" href="https://www.geeksforgeeks.org/equation-of-circle-when-three-points-on-the-circle-are-given/">https://www.geeksforgeeks.org/equation-of-circle-when-three-points-on-the-circle-are-given/</a>"<br>
    x12 _ x1 - x2.<br>
    x13 _ x1 - x3.<br>
    y12 _ y1 - y2.<br>
    y13 _ y1 - y3.<br>
    y31 _ y3 - y1.<br>
    y21 _ y2 - y1.<br>
    x31 _ x3 - x1.<br>
    x21 _ x2 - x1.<br>
    sx13 _ x1 squared - x3 squared.<br>
    sy13 _ y1 squared - y3 squared.<br>
    sx21 _ x2 squared - x1 squared.<br>
    sy21 _ y2 squared - y1 squared.<br>
    f _  ((sx13 * x12)<br>
                + (sy13 * x12)<br>
                + (sx21 * x13)<br>
                + (sy21 * x13))<br>
                / (2 * ((y31 * x12) - (y21 * x13))).<br>
    g _  ((sx13 * y12)<br>
                + (sy13 * y12)<br>
                + (sx21 * y13)<br>
                + (sy21 * y13))<br>
                / (2 * ((x31 * y12) - (x21 * y13))).<br>
    c _ 0 - x1 squared - y1 squared - (2 * g *x1) - (2 * f * y1).<br>
     "    // eqn of circle be<br>
        // x^2 + y^2 + 2*g*x + 2*f*y + c = 0<br>
        // where centre is (h = -g, k = -f) and radius r<br>
        // as r^2 = h^2 + k^2 - c"<br>
    h _ g negated.<br>
    k _ f negated.<br>
    center _ h@k.<br>
    rSquared _ h squared + k squared - c.<br>
     "    // r is the radius"<br>
    r _ rSquared sqrt.<br>
    "Ok. Found center and r. That's all we wanted."<br>
    start _ x1 @ y1.<br>
    end _ x3 @ y3.<br>
    mid _ x2@y2.<br>
    alpha1 _ ((mid - center) theta radiansToDegrees - (start - center)
    theta radiansToDegrees) \\ 360.<br>
    alpha2 _ ((end - center) theta radiansToDegrees - (start - center)
    theta radiansToDegrees) \\ 360.<br>
    alpha1 > alpha2<br>
        ifTrue: [<br>
            alpha1 _ alpha1 - 360.<br>
            alpha2 _ alpha2 - 360.<br>
            orientation _ false ]<br>
        ifFalse: [<br>
            orientation _ true ].<br>
    largeFlag _ alpha2 abs > 180.<br>
    canvas _ VectorCanvas onForm: Display.<br>
    canvas ellipseCenterX: x1 y: y1 rx: 15 ry: 15 borderWidth: 5
    borderColor: Color red fillColor: Color yellow.<br>
    canvas ellipseCenterX: x2 y: y2 rx: 15 ry: 15 borderWidth: 5
    borderColor: Color red fillColor: Color orange.<br>
    canvas ellipseCenterX: x3 y: y3 rx: 15 ry: 15 borderWidth: 5
    borderColor: Color red fillColor: Color red.<br>
    canvas strokeWidth: 5 color: Color red do: [<br>
            canvas moveToX: start x y: start y;<br>
            arcToX: end x y: end y rx: r ry: r angleOfXAxis: 0
    largeFlag: largeFlag sweepFlag: orientation ].<br>
    Display forceToScreen<br>
    <br>
    Hope this helps.<br>
    <br>
    Cheers,<br>
    <pre class="moz-signature" cols="72">-- 
Juan Vuletich
<a class="moz-txt-link-abbreviated" href="http://www.cuis-smalltalk.org">www.cuis-smalltalk.org</a>
<a class="moz-txt-link-freetext" href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a>
<a class="moz-txt-link-freetext" href="https://github.com/jvuletich">https://github.com/jvuletich</a>
<a class="moz-txt-link-freetext" href="https://www.linkedin.com/in/juan-vuletich-75611b3">https://www.linkedin.com/in/juan-vuletich-75611b3</a>
@JuanVuletich

</pre>
  </body>
</html>