Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Mathematica code help

  1. Jun 14, 2009 #1
    Hello,
    I am writing a code in Mathematica to draw chain segements (Conformal Geometry - Hermetian matrix chains).
    The purpose of the code is to take 3 complex numbers as input and test if they are collinear or not. If collinear, output should be a line else a circle or an arc passing through the 3 points. Below is the function DrawChainSegment so far.

    DrawChainSegment[z0_, z1_, z2_] := Module[{output},
    output = Line[{ToR2[zo], ToR2[z2]}];
    Return[output];] /; LinearDependent[z2 - z1, z0 - z1];
    DrawChainSegment[z0_, z1_, z2_] :=
    Module[{}, "The case where we have a circle"] /; z0 == 0;

    I am stuck at this so kindly suggest how to make the first case of drawing a line work and also help me in completing the module for the circle case. Any suggestions or tips are welcome. Thank you.
     
  2. jcsd
  3. Jun 15, 2009 #2

    Dale

    Staff: Mentor

    Hi relroy,

    Welcome to PF! I would recommend looking at equations 28-34 on http://mathworld.wolfram.com/Circle.html

    If a=0 (eq 31) then the points are colinear and the radius of the circle is infinite. Otherwise, you will need to have the center and radius to draw the circle anyway, so there is no wasted effort using these.
     
  4. Jun 15, 2009 #3
    Hello Dale,

    Thanks for the reply. I went through those equations but I am not actually looking to draw a circle. It is just an arc of the circle which goes from one endpoint to the other passing through the point between ie my aim is to just join 3 points.
    In other words I have to give three points z0, z1 and z2 as inputs. Assuming they are non collinear, is there some function to join these three points in the form of an arc? Will LinePlot or Plot work here to give an arc as the output or is there some other function?

    Thanks
     
  5. Jun 15, 2009 #4

    Dale

    Staff: Mentor

    Not as far as I know. The function Circle takes as its argument the center and the radius and optionally the starting angle and ending angle. For the center and radius you can use the equations I linked to, and you can use ArcTan to get the starting and ending angles.
     
  6. Jun 16, 2009 #5
    Thanks again for the reply Dale. One last q:-
    Now there are three points on the circumference of the circle joining which we get 2 chords, like in here -> http://local.wasp.uwa.edu.au/~pbourke/geometry/circlefrom3/

    The perpendicular bisectors of these 2 chords meet at the center. And distance from this center to one of the 3 points on the circumference gives the radius.
    Now how to represent these perpendicular bisector to determine center and radius in the mathematica module for drawing arc of circle.

    Any help welcome.
     
    Last edited by a moderator: Apr 24, 2017
  7. Jun 16, 2009 #6

    Dale

    Staff: Mentor

    Do you actually want the perpendicular bisectors for some reason or are you just trying to find the center and radius?

    If you just want the center and radius then I would skip the whole perpendicular bisector thing and just use the direct equations in the link I posted. Finding the perpendicular bisectors is a lot of work to throw away.
     
  8. Jun 16, 2009 #7
    Yes I only want to find center and radius. And these equations do look like they will work. But I have a few, last possibly elementary questions abt this circle module.

    Since the inputs I have are complex numbers z0,z1,z2 and these equations need me to add the squares of the coordinates. For instance eqn 32 for d has x1^2 + y1^2 as one of the matrix elements.
    So in my case should I put Re[zo]^2 + Im[z0]^2 etc and will that work?

    And arent these variables a,d,e,f equal to determinants? So that calls for first defining the matrices then using Det command?
    Your help is much appreciated :)
     
  9. Jun 16, 2009 #8

    Dale

    Staff: Mentor

    Yes. Alternatively you could use Abs[z0]^2

    Also yes, although you can do both in a single step.
     
    Last edited: Jun 16, 2009
  10. Jul 7, 2009 #9
    Hi again,
    This time I have question about drawing line segments. I have a code to draw a line joining 3 collinear points:-
    DrawChainSegment[z0_, z1_, z2_] :=
    Module[{output, \[Gamma], t, endpoint1, endpoint2},
    If[ToR2[z2 - z1].ToR2[z0 - z1] < 0,
    (*The output is a single line segment*)
    output = Line[{ToR2[z0], ToR2[z2]}];,
    (*The output is 2 rays passing through infinity*)
    \[Gamma] = z1 + t*(z2 - z1)/Norm[z2 - z1];
    endpoint1 = \[Gamma] /. {t -> -100};
    endpoint2 = \[Gamma] /. {t -> 100};
    output = {Line[{ToR2[endpoint1], ToR2[z1]}],
    Line[{ToR2[z2], ToR2[endpoint2]}]};
    ];
    Return[output];
    ] /; LinearDependentQ[z2 - z0, z1 - z0];

    Now I want help drawing a similar function with one small difference being that one of the 3 points will be ComplexInfinity. For instance DrawChainSegment[z0,ComplexInfinity,z2]. Please advise on how to go about this. Thanks a lot!
     
  11. Jul 7, 2009 #10

    Dale

    Staff: Mentor

    Hi relroy,

    What does it mean graphically or geometrically for a line to go through ComplexInfinity? I know that complex infinity is "far away", but which direction?
     
  12. Jul 7, 2009 #11
    For [z0,Complexinfinity,z2] we have to draw a line going from z0 to a distant point ("infinity") then second line coming from "infinity" to z2. This "infinity" lies to left of z0 and right of z2 so it should like:-
    _________________. z0 z2._____________________ with big gap between z0 and z2

    And for [ComplexInfinity,z1,z2] it could be like this:-
    ________________.z1_____________.z2 with no gap between z0 and z2
     
    Last edited: Jul 7, 2009
  13. Jul 8, 2009 #12

    Dale

    Staff: Mentor

    OK, I understand. Could you send your code for ToR2 and LinearDependentQ, the code for DrawChainSegment depends on both.
     
  14. Jul 8, 2009 #13
    ToR2 and LinearDependentQ are inbuilt functions. ToR2 of a+bi returns (a,b) and lineardependentq checks if the inputs are collinear.
     
  15. Jul 8, 2009 #14

    Dale

    Staff: Mentor

    I am using version 7.0.0 and it does not show up. Are you loading them from any packages or something?
     
  16. Jul 8, 2009 #15
    Sorry abt that, I am indeed using this package called ConformalGeometry.nb and they are defined somewhere in there.
    Is the code for these 2 needed or is their usage enough? Your help is much appreciated.
     
    Last edited: Jul 8, 2009
  17. Jul 8, 2009 #16

    Dale

    Staff: Mentor

    Hi relroy,

    The way you have your function declared it already draws this as long as the first point is between the second two points. So all you have to do is define:

    DrawChainSegment[z0_, ComplexInfinity, z2_] := DrawChainSegment[(z0 + z2)/2, z0, z2]

    You should be able to define similar functions for the ComplexInfinity in the other two locations.
     
  18. Jul 8, 2009 #17
    Wow its a simple solution and serves the purpose! Thanks Dale!

    I have one more query. This time about the circular arc which you helped with in the previous posts. The problem with the current function shown below is that is startingangle is less than endingangle it draws the arc but if its greater than endingangle, it draws the full circle excluding the required arc.
    DrawChainSegment[z0_, z1_, z2_] :=
    Module[{a, d, e, f, x, y, rad, startangle, endangle, circle},
    a = Det[{{Re[z0], Im[z0], 1}, {Re[z1], Im[z1], 1}, {Re[z2],
    Im[z2], 1}}];
    d = -Det[{{Abs[z0]^2, Im[z0], 1}, {Abs[z1]^2, Im[z1],
    1}, {Abs[z2]^2, Im[z2], 1}}];
    e = Det[{{Abs[z0]^2, Re[z0], 1}, {Abs[z1]^2, Re[z1],
    1}, {Abs[z2]^2, Re[z2], 1}}];
    f = -Det[{{Abs[z0]^2, Re[z0], Im[z0]}, {Abs[z1]^2, Re[z1],
    Im[z1]}, {Abs[z2]^2, Re[z2], Im[z2]}}];
    x = -d/(2 a);
    y = -e/(2 a);
    rad = Sqrt[(d^2 + e^2)/(4*a^2) - (f/a)];
    startangle = Arg[z0 - (x + I*y)];
    endangle = Arg[z2 - (x + I*y)];
    (*Somehow need to make sure these angles are in the correct \
    order...will require some If with different cases*)
    circle = Circle[{x, y}, rad, {startangle, endangle}];
    Return[circle];] /; ! (LinearDependentQ[z2 - z0, z1 - z0]);

    For Graphics[DrawChainSegment[1, I, 4]] it draws a nice arc as needed but for Graphics[DrawChainSegment[10, I, 4]]it draws the longer path but what is actually required is for it to go in the other direction and give the small arc as before.

    So the question is to somehow make sure the angles are in correct order. I thought of using Sort function or using if statements and maybe adding 2Pi to both or one of the angles and bring it in order but Im unable to implement it. Any thoughts on this problem? Thanks a mil for all the help!
     
  19. Jul 8, 2009 #18

    Dale

    Staff: Mentor

    You are welcome.

    How about:
    {startangle, endangle} = Sort[{Arg[...],Arg[...]}]

    You could even get rid of startangle and endangle and just have one variable:
    angles = Sort[{Arg[...],Arg[...]}];
    circle = Circle[..., angles];
     
  20. Jul 8, 2009 #19
    I tried the above suggestions but it gives the wrong output ie. the big circle - the required arc even for [1,I,4]

    In the present function: for smaller startangles eg,[1,I,4] we get correct output but for greater startangles eg.[10,I,4] we get wrong output. Can you think of some other way to make it work for all inputs? Howabout some if statements with conditions in case startangle > endangle etc?
    Thanks for the effort.
     
  21. Jul 8, 2009 #20

    Dale

    Staff: Mentor

    Does it always give the wrong output, or only sometimes? If it is always wrong then a simple

    Reverse[Sort[...]]

    would do the trick.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook