# Mathematica code help

1. Jun 14, 2009

### relroy

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. Jun 15, 2009

### 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.

3. Jun 15, 2009

### relroy

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

4. Jun 15, 2009

### 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.

5. Jun 16, 2009

### relroy

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
6. Jun 16, 2009

### 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.

7. Jun 16, 2009

### relroy

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 :)

8. Jun 16, 2009

### 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
9. Jul 7, 2009

### relroy

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!

10. Jul 7, 2009

### 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?

11. Jul 7, 2009

### relroy

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
12. Jul 8, 2009

### Staff: Mentor

OK, I understand. Could you send your code for ToR2 and LinearDependentQ, the code for DrawChainSegment depends on both.

13. Jul 8, 2009

### relroy

ToR2 and LinearDependentQ are inbuilt functions. ToR2 of a+bi returns (a,b) and lineardependentq checks if the inputs are collinear.

14. Jul 8, 2009

### Staff: Mentor

I am using version 7.0.0 and it does not show up. Are you loading them from any packages or something?

15. Jul 8, 2009

### relroy

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
16. Jul 8, 2009

### 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.

17. Jul 8, 2009

### relroy

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!

18. Jul 8, 2009

### Staff: Mentor

You are welcome.

{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];

19. Jul 8, 2009

### relroy

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.

20. Jul 8, 2009

### 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.