ASKSAGE: Sage Q&A Forum - Individual question feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Mon, 16 Mar 2020 22:19:36 -0500Is it possible to determine if a line segment is present between two points on a 3d graphic object?https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/Hello everyone. I'm working on a program which plots 3D molecular structures and associated point group symmetries. I've had some issues figuring out how to fill in the remaining single bonds of a six member ring (aromatic class) after the user dictates where double bonds should be placed. These aromatics are basically 6 member cycle graphs for the purposes of my problem. Is there any way to evaluate two coordinates (atoms) on a 3d graphic object (molecule) and check if a line segment (bond) has already been added between them? By necessity any pi (double) bond should only be connected to the adjacent, (non pi-bonded) atom. So for example if there was a pi bond present between Atoms 1 and 2 of a ring then we should have single bonds between A6-A1 and A2-A3. The code below is how I am currently approaching that problem.
A1,A2,A3,A4,A6 are fixed, three dimensional coordinates associated with each position on the ring.
Bonds = str(input('Enter pi bond atomic pair in format "A1-A2" or type PLOT: '))
while (Bonds != 'PLOT'):
Bonds2 = Bonds.split('-')
for bond in Bonds2:
if bond == 'A1':
pi_list.append(A1)
elif bond == 'A2':
pi_list.append(A2)
elif bond == 'A3':
pi_list.append(A3)
elif bond == 'A4':
pi_list.append(A4)
elif bond == 'A5':
pi_list.append(A5)
elif bond == 'A6':
pi_list.append(A6)
if pi_list != []:
x += pi_bond(x,pi_list[0], pi_list[1])
for atom in Coords:
for pi_atom in pi_list:
if (atom != pi_list[0]) and (atom != pi_list[1]) and (float(distance(pi_atom,atom))==float(distance(A1,A2))):
x += single_bond(pi_atom, atom)
pi_list.clear()
if (Bonds == 'PLOT'):
break
Bonds = str(input('Enter additional pi bonds or type PLOT: '))
Can anyone think of a more elegant way to approach this?
Here is the function I am currently using to add a double bond between two points:
def pi_bond(x,Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return xMon, 16 Mar 2020 14:22:28 -0500https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/Comment by RyanG for <p>Hello everyone. I'm working on a program which plots 3D molecular structures and associated point group symmetries. I've had some issues figuring out how to fill in the remaining single bonds of a six member ring (aromatic class) after the user dictates where double bonds should be placed. These aromatics are basically 6 member cycle graphs for the purposes of my problem. Is there any way to evaluate two coordinates (atoms) on a 3d graphic object (molecule) and check if a line segment (bond) has already been added between them? By necessity any pi (double) bond should only be connected to the adjacent, (non pi-bonded) atom. So for example if there was a pi bond present between Atoms 1 and 2 of a ring then we should have single bonds between A6-A1 and A2-A3. The code below is how I am currently approaching that problem.</p>
<p>A1,A2,A3,A4,A6 are fixed, three dimensional coordinates associated with each position on the ring.</p>
<pre><code>Bonds = str(input('Enter pi bond atomic pair in format "A1-A2" or type PLOT: '))
while (Bonds != 'PLOT'):
Bonds2 = Bonds.split('-')
for bond in Bonds2:
if bond == 'A1':
pi_list.append(A1)
elif bond == 'A2':
pi_list.append(A2)
elif bond == 'A3':
pi_list.append(A3)
elif bond == 'A4':
pi_list.append(A4)
elif bond == 'A5':
pi_list.append(A5)
elif bond == 'A6':
pi_list.append(A6)
if pi_list != []:
x += pi_bond(x,pi_list[0], pi_list[1])
for atom in Coords:
for pi_atom in pi_list:
if (atom != pi_list[0]) and (atom != pi_list[1]) and (float(distance(pi_atom,atom))==float(distance(A1,A2))):
x += single_bond(pi_atom, atom)
pi_list.clear()
if (Bonds == 'PLOT'):
break
Bonds = str(input('Enter additional pi bonds or type PLOT: '))
</code></pre>
<p>Can anyone think of a more elegant way to approach this?</p>
<p>Here is the function I am currently using to add a double bond between two points:</p>
<pre><code>def pi_bond(x,Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
</code></pre>
https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50279#post-id-50279I have fixed the issue and updated the code. Thank you again.Mon, 16 Mar 2020 22:19:36 -0500https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50279#post-id-50279Comment by RyanG for <p>Hello everyone. I'm working on a program which plots 3D molecular structures and associated point group symmetries. I've had some issues figuring out how to fill in the remaining single bonds of a six member ring (aromatic class) after the user dictates where double bonds should be placed. These aromatics are basically 6 member cycle graphs for the purposes of my problem. Is there any way to evaluate two coordinates (atoms) on a 3d graphic object (molecule) and check if a line segment (bond) has already been added between them? By necessity any pi (double) bond should only be connected to the adjacent, (non pi-bonded) atom. So for example if there was a pi bond present between Atoms 1 and 2 of a ring then we should have single bonds between A6-A1 and A2-A3. The code below is how I am currently approaching that problem.</p>
<p>A1,A2,A3,A4,A6 are fixed, three dimensional coordinates associated with each position on the ring.</p>
<pre><code>Bonds = str(input('Enter pi bond atomic pair in format "A1-A2" or type PLOT: '))
while (Bonds != 'PLOT'):
Bonds2 = Bonds.split('-')
for bond in Bonds2:
if bond == 'A1':
pi_list.append(A1)
elif bond == 'A2':
pi_list.append(A2)
elif bond == 'A3':
pi_list.append(A3)
elif bond == 'A4':
pi_list.append(A4)
elif bond == 'A5':
pi_list.append(A5)
elif bond == 'A6':
pi_list.append(A6)
if pi_list != []:
x += pi_bond(x,pi_list[0], pi_list[1])
for atom in Coords:
for pi_atom in pi_list:
if (atom != pi_list[0]) and (atom != pi_list[1]) and (float(distance(pi_atom,atom))==float(distance(A1,A2))):
x += single_bond(pi_atom, atom)
pi_list.clear()
if (Bonds == 'PLOT'):
break
Bonds = str(input('Enter additional pi bonds or type PLOT: '))
</code></pre>
<p>Can anyone think of a more elegant way to approach this?</p>
<p>Here is the function I am currently using to add a double bond between two points:</p>
<pre><code>def pi_bond(x,Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
</code></pre>
https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50276#post-id-50276I think this will be a much better approach and I imagine any answer to that question would have taken me down a much more complicated rabbit hole.Mon, 16 Mar 2020 17:31:35 -0500https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50276#post-id-50276Comment by John Palmieri for <p>Hello everyone. I'm working on a program which plots 3D molecular structures and associated point group symmetries. I've had some issues figuring out how to fill in the remaining single bonds of a six member ring (aromatic class) after the user dictates where double bonds should be placed. These aromatics are basically 6 member cycle graphs for the purposes of my problem. Is there any way to evaluate two coordinates (atoms) on a 3d graphic object (molecule) and check if a line segment (bond) has already been added between them? By necessity any pi (double) bond should only be connected to the adjacent, (non pi-bonded) atom. So for example if there was a pi bond present between Atoms 1 and 2 of a ring then we should have single bonds between A6-A1 and A2-A3. The code below is how I am currently approaching that problem.</p>
<p>A1,A2,A3,A4,A6 are fixed, three dimensional coordinates associated with each position on the ring.</p>
<pre><code>Bonds = str(input('Enter pi bond atomic pair in format "A1-A2" or type PLOT: '))
while (Bonds != 'PLOT'):
Bonds2 = Bonds.split('-')
for bond in Bonds2:
if bond == 'A1':
pi_list.append(A1)
elif bond == 'A2':
pi_list.append(A2)
elif bond == 'A3':
pi_list.append(A3)
elif bond == 'A4':
pi_list.append(A4)
elif bond == 'A5':
pi_list.append(A5)
elif bond == 'A6':
pi_list.append(A6)
if pi_list != []:
x += pi_bond(x,pi_list[0], pi_list[1])
for atom in Coords:
for pi_atom in pi_list:
if (atom != pi_list[0]) and (atom != pi_list[1]) and (float(distance(pi_atom,atom))==float(distance(A1,A2))):
x += single_bond(pi_atom, atom)
pi_list.clear()
if (Bonds == 'PLOT'):
break
Bonds = str(input('Enter additional pi bonds or type PLOT: '))
</code></pre>
<p>Can anyone think of a more elegant way to approach this?</p>
<p>Here is the function I am currently using to add a double bond between two points:</p>
<pre><code>def pi_bond(x,Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
</code></pre>
https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50274#post-id-50274Oh, and to try to answer your original question: I don't know of any way to determine whether a line segment is present in a graphics object. I am not an expert in the graphics part of Sage, though.Mon, 16 Mar 2020 17:22:50 -0500https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50274#post-id-50274Comment by RyanG for <p>Hello everyone. I'm working on a program which plots 3D molecular structures and associated point group symmetries. I've had some issues figuring out how to fill in the remaining single bonds of a six member ring (aromatic class) after the user dictates where double bonds should be placed. These aromatics are basically 6 member cycle graphs for the purposes of my problem. Is there any way to evaluate two coordinates (atoms) on a 3d graphic object (molecule) and check if a line segment (bond) has already been added between them? By necessity any pi (double) bond should only be connected to the adjacent, (non pi-bonded) atom. So for example if there was a pi bond present between Atoms 1 and 2 of a ring then we should have single bonds between A6-A1 and A2-A3. The code below is how I am currently approaching that problem.</p>
<p>A1,A2,A3,A4,A6 are fixed, three dimensional coordinates associated with each position on the ring.</p>
<pre><code>Bonds = str(input('Enter pi bond atomic pair in format "A1-A2" or type PLOT: '))
while (Bonds != 'PLOT'):
Bonds2 = Bonds.split('-')
for bond in Bonds2:
if bond == 'A1':
pi_list.append(A1)
elif bond == 'A2':
pi_list.append(A2)
elif bond == 'A3':
pi_list.append(A3)
elif bond == 'A4':
pi_list.append(A4)
elif bond == 'A5':
pi_list.append(A5)
elif bond == 'A6':
pi_list.append(A6)
if pi_list != []:
x += pi_bond(x,pi_list[0], pi_list[1])
for atom in Coords:
for pi_atom in pi_list:
if (atom != pi_list[0]) and (atom != pi_list[1]) and (float(distance(pi_atom,atom))==float(distance(A1,A2))):
x += single_bond(pi_atom, atom)
pi_list.clear()
if (Bonds == 'PLOT'):
break
Bonds = str(input('Enter additional pi bonds or type PLOT: '))
</code></pre>
<p>Can anyone think of a more elegant way to approach this?</p>
<p>Here is the function I am currently using to add a double bond between two points:</p>
<pre><code>def pi_bond(x,Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
</code></pre>
https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50271#post-id-50271Am I understanding correctly that you're suggesting I create a default position dictionary that would like something like:
graph = { A1 : [A2, A6], A2 : [A1, A3], A3 : [A2, A4], A4: [A3, A5], A5: [A4, A6], A6: [A5, A1] }
This way when a user adds a pi bond pair ie A1-A2 I can delete the pairing from the default dictionary and add them to a second dictionary for double bonds or something to that effect. Much more elegant. Thank you for the suggestion.Mon, 16 Mar 2020 15:59:10 -0500https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50271#post-id-50271Comment by John Palmieri for <p>Hello everyone. I'm working on a program which plots 3D molecular structures and associated point group symmetries. I've had some issues figuring out how to fill in the remaining single bonds of a six member ring (aromatic class) after the user dictates where double bonds should be placed. These aromatics are basically 6 member cycle graphs for the purposes of my problem. Is there any way to evaluate two coordinates (atoms) on a 3d graphic object (molecule) and check if a line segment (bond) has already been added between them? By necessity any pi (double) bond should only be connected to the adjacent, (non pi-bonded) atom. So for example if there was a pi bond present between Atoms 1 and 2 of a ring then we should have single bonds between A6-A1 and A2-A3. The code below is how I am currently approaching that problem.</p>
<p>A1,A2,A3,A4,A6 are fixed, three dimensional coordinates associated with each position on the ring.</p>
<pre><code>Bonds = str(input('Enter pi bond atomic pair in format "A1-A2" or type PLOT: '))
while (Bonds != 'PLOT'):
Bonds2 = Bonds.split('-')
for bond in Bonds2:
if bond == 'A1':
pi_list.append(A1)
elif bond == 'A2':
pi_list.append(A2)
elif bond == 'A3':
pi_list.append(A3)
elif bond == 'A4':
pi_list.append(A4)
elif bond == 'A5':
pi_list.append(A5)
elif bond == 'A6':
pi_list.append(A6)
if pi_list != []:
x += pi_bond(x,pi_list[0], pi_list[1])
for atom in Coords:
for pi_atom in pi_list:
if (atom != pi_list[0]) and (atom != pi_list[1]) and (float(distance(pi_atom,atom))==float(distance(A1,A2))):
x += single_bond(pi_atom, atom)
pi_list.clear()
if (Bonds == 'PLOT'):
break
Bonds = str(input('Enter additional pi bonds or type PLOT: '))
</code></pre>
<p>Can anyone think of a more elegant way to approach this?</p>
<p>Here is the function I am currently using to add a double bond between two points:</p>
<pre><code>def pi_bond(x,Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
</code></pre>
https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50270#post-id-50270I would maintain all of the data for the molecule without doing any plotting, for example as a dictionary. Then it's easy to add and delete entries. When you're ready to plot, create the plot.Mon, 16 Mar 2020 15:22:40 -0500https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?comment=50270#post-id-50270Answer by RyanG for <p>Hello everyone. I'm working on a program which plots 3D molecular structures and associated point group symmetries. I've had some issues figuring out how to fill in the remaining single bonds of a six member ring (aromatic class) after the user dictates where double bonds should be placed. These aromatics are basically 6 member cycle graphs for the purposes of my problem. Is there any way to evaluate two coordinates (atoms) on a 3d graphic object (molecule) and check if a line segment (bond) has already been added between them? By necessity any pi (double) bond should only be connected to the adjacent, (non pi-bonded) atom. So for example if there was a pi bond present between Atoms 1 and 2 of a ring then we should have single bonds between A6-A1 and A2-A3. The code below is how I am currently approaching that problem.</p>
<p>A1,A2,A3,A4,A6 are fixed, three dimensional coordinates associated with each position on the ring.</p>
<pre><code>Bonds = str(input('Enter pi bond atomic pair in format "A1-A2" or type PLOT: '))
while (Bonds != 'PLOT'):
Bonds2 = Bonds.split('-')
for bond in Bonds2:
if bond == 'A1':
pi_list.append(A1)
elif bond == 'A2':
pi_list.append(A2)
elif bond == 'A3':
pi_list.append(A3)
elif bond == 'A4':
pi_list.append(A4)
elif bond == 'A5':
pi_list.append(A5)
elif bond == 'A6':
pi_list.append(A6)
if pi_list != []:
x += pi_bond(x,pi_list[0], pi_list[1])
for atom in Coords:
for pi_atom in pi_list:
if (atom != pi_list[0]) and (atom != pi_list[1]) and (float(distance(pi_atom,atom))==float(distance(A1,A2))):
x += single_bond(pi_atom, atom)
pi_list.clear()
if (Bonds == 'PLOT'):
break
Bonds = str(input('Enter additional pi bonds or type PLOT: '))
</code></pre>
<p>Can anyone think of a more elegant way to approach this?</p>
<p>Here is the function I am currently using to add a double bond between two points:</p>
<pre><code>def pi_bond(x,Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
x += LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
x += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return x
</code></pre>
https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?answer=50273#post-id-50273Using John Palmieri's suggestion I created a default dictionary of single bonds and an empty dictionary for pi bonds:
When a pi bond pair is added to Pi_Dict, the pairing from Sigma_Dict is deleted
I was not aware that lists could be entered into dictionaries and this will make my work much easier.
**Updated code:**
import sys
from sage.plot.plot3d.shapes import LineSegment, Sphere
from sage.plot.colors import rainbow
from sage.plot.plot3d.implicit_plot3d import implicit_plot3d
from sage.plot.plot3d.shapes2 import text3d
from sage.repl.rich_output.pretty_print import show
Radii = {'O': 0.73, 'N': 0.75, 'C': 0.77, 'He': 0.32, 'H': 0.37, 'S': 1.02, 'Cl': 0.99,
'F': 0.71, 'Xe': 1.30, 'Si': 1.11, 'B': 0.82, 'P': 1.06, 'Br': 1.14}
Valency = {'O': 6, 'N': 5, 'C': 4, 'He': 0, 'H': 1, 'S': 6, 'Cl': 7,
'F': 7, 'Xe': 8, 'Si': 4, 'B': 3, 'P': 5, 'Br': 7}
Colors = {'O': 'red', 'N': 'green', 'C': 'black', 'He': 'cyan', 'H': 'white', 'S': 'yellow',
'Si': 'purple', 'Xe': 'pink', 'F': 'blue', 'Cl': 'green', 'B': 'pink', 'P': 'orange',
'Br': 'red'}
X = int(input('Enter x axis shift or press enter for default: '))
def distance(A,B):
D = float(((B[0]-A[0])**2 + (B[1]-A[1])**2 + (B[2]-A[2])**2)**(1/2))
return D
def Normalize(x):
x = (float(x)/0.77)*0.20
return x
O = (X,0,0)
A2 = (X, 1, 0.559)
A3 = (X, 1, -0.559)
A5 = (X, -1, -0.559)
A6 = (X, -1, 0.559)
A1 = (X, 0, distance(A2,A3))
A4 = (X, 0,-1*distance(A2,A3))
Sigma_Dict = { 'A1-A2' : [A1,A2], 'A2-A3' : [A2,A3], 'A3-A4' : [A3,A4], 'A4-A5' : [A4,A5], 'A5-A6' : [A5,A6], 'A1-A6' : [A1, A6] }
Pi_Dict = { 'A1-A2' : [A1,A2], 'A5-A6' : [A5,A6], 'A3-A4': [A3,A4] }
Atomic_Position = { A1: 'Br', A2: 'C', A3: 'Cl', A4: 'C', A5: 'B', A6: 'C' }
def bond_split(AxAy):
x = AxAy[0]
y = AxAy[1]
return(x,y)
def pi_bond(Cx,Cy):
X = 0.05
if Cx[1] == Cy[1]:
Ca = Cx[1]-X
Cb = Cx[1]+X
Cc = Cy[1]-X
Cd = Cy[1]+X
Cx1 = (Cx[0], Ca, Cx[2])
Cx2 = (Cx[0], Cb, Cx[2])
Cy1 = (Cy[0], Cc, Cy[2])
Cy2 = (Cy[0], Cd, Cy[2])
D = LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
D += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return (D)
else:
Ca = Cx[2]-X
Cb = Cx[2]+X
Cc = Cy[2]-X
Cd = Cy[2]+X
Cx1 = (Cx[0], Cx[1], Ca)
Cx2 = (Cx[0], Cx[1], Cb)
Cy1 = (Cy[0], Cy[1], Cc)
Cy2 = (Cy[0], Cy[1], Cd)
D = LineSegment(Cx1, Cy1, 1, color='white', axes=False, frame=False)
D += LineSegment(Cx2, Cy2, 1, color='white', axes=False, frame=False)
return (D)
Benzene = Sphere(.000001, color='white').translate(O)
for atom in Atomic_Position:
Benzene += Sphere(Normalize(Radii[Atomic_Position[atom]]), color=Colors[Atomic_Position[atom]]).translate(atom)
for pi in Pi_Dict:
if pi in Sigma_Dict:
del Sigma_Dict[pi]
for pi in Pi_Dict:
Benzene += pi_bond(bond_split(Pi_Dict[pi])[0],bond_split(Pi_Dict[pi])[1])
for bond in Sigma_Dict:
Benzene += LineSegment(bond_split(Sigma_Dict[bond])[0],bond_split(Sigma_Dict[bond])[1], 1, color= 'white' )
show(Benzene)Mon, 16 Mar 2020 17:10:00 -0500https://ask.sagemath.org/question/50269/is-it-possible-to-determine-if-a-line-segment-is-present-between-two-points-on-a-3d-graphic-object/?answer=50273#post-id-50273