Mathematica Code Help: Draw Chain Segments

In summary: 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}; (*The code fails at this point. It seems
  • #1
relroy
13
0
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.
 
Physics news on Phys.org
  • #2
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
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
relroy said:
is there some function to join these three points in the form of an arc?
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
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:
  • #6
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
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
relroy said:
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?
Yes. Alternatively you could use Abs[z0]^2

relroy said:
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 :)
Also yes, although you can do both in a single step.
 
Last edited:
  • #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!
 
  • #10
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
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:
  • #12
OK, I understand. Could you send your code for ToR2 and LinearDependentQ, the code for DrawChainSegment depends on both.
 
  • #13
ToR2 and LinearDependentQ are inbuilt functions. ToR2 of a+bi returns (a,b) and lineardependentq checks if the inputs are collinear.
 
  • #14
I am using version 7.0.0 and it does not show up. Are you loading them from any packages or something?
 
  • #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:
  • #16
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
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 I am unable to implement it. Any thoughts on this problem? Thanks a mil for all the help!
 
  • #18
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];
 
  • #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.
 
  • #20
Does it always give the wrong output, or only sometimes? If it is always wrong then a simple

Reverse[Sort[...]]

would do the trick.
 
  • #21
Yes! I think that does the trick. Thanks for your patience its been a great help.
If I get any other qs I know where to come :-)
 
  • #23
Hello again Dale,

I was testing the codes and I found that it doesn't work for all inputs. Examples for which inputs are not as expected:-
(i)[I,2I,4I] -> No output graph just a message saying DrawChainSegment is not a graphics prmitive or directive
(ii)[1,2,4] -> Same o/p as above, if all 3 inputs are complex or real we get this message so should we use some if condition to solve this?
(iii)[I,2,4] -> Message saying starting angle is greater than ending angle and the same old problem of bigger arc as output
Here is the code:-
DrawChainSegment[z0_, z1_, z2_] :=
Module[{a, d, e, f, x, y, rad, angles, 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)];
angles = Reverse[Sort[{Arg[z0 - (x + I*y)], Arg[z2 - (x + I*y)]}]];
circle = Circle[{x, y}, rad, angles];
Return[circle];] /; ! (LinearDependentQ[z2 - z0, z1 - z0]);


Second issue is for the drawing lines for complexinfinity inputs, the first case works fine as ur suggestion was followed. But these 2 cases DrawChainSegment[ComplexInfinity, z1_, z2_] and DrawChainSegment[z0_, z1_, ComplexInfinity] don't give one continuous line as expected output. I tried DrawChainSegment[ComplexInfinity, z1_, z2_] :=
DrawChainSegment[z1, z2, (z1*z2)]; and (z1+z2) etc but not getting that continuous line as ouput

Reply at leisure.
 
Last edited:
  • #24
Hi relroy

I can't test it out right now, but if it is not a graphics object then the most likely cause would be that the LinearDependentQ condition is not evaluating to True.
 
  • #25
Ok will look into that.

Any thought on the complexinfinity input part?
 

1. How do I draw a chain segment in Mathematica?

To draw a chain segment in Mathematica, you can use the built-in function "Line" and specify the coordinates of the points that make up the segment. For example, if you want to draw a chain segment from (0,0) to (1,1), you would use the code "Line[{{0,0},{1,1}}]".

2. Can I customize the appearance of the chain segment?

Yes, you can customize the appearance of the chain segment by using options in the "Line" function. For example, you can change the color, thickness, and style of the line by specifying the appropriate options in the code. You can also add arrowheads or labels to the segment.

3. How do I draw multiple chain segments in one plot?

To draw multiple chain segments in one plot, you can use the "Graphics" function in Mathematica. First, define each segment as a separate "Line" object, and then combine them using the "Show" function. This will create a single plot with all the segments included.

4. Can I animate the chain segments?

Yes, you can animate the chain segments by using the "Animate" function in Mathematica. You can specify the starting and ending points of each segment and control the speed of the animation. This is helpful for visualizing how the chain segments move and interact with each other.

5. Are there any built-in functions for drawing more complex chain structures?

Yes, Mathematica has built-in functions for drawing more complex chain structures, such as "Polygon" for closed loop chains and "BezierCurve" for curved segments. You can also use the "Graph" function to create chain structures with multiple interconnected segments.

Back
Top