I have plotted a series of blue and red spheres to replicate an atomic structure.
I would like the blue and red spheres to remain distinct; such that when I rotate the model, and the spheres overlap, the colours stay blue and red.
The problem I am facing is that the colours mix where the spheres overlap.
E.g) Plotting Blue and Red spheres. I want the spheres to remain blue of red, however when I move the camera, the overlapping spheres appear pink at the intersection.
How do I stop the colours from mixing into this purple-ish tone and keep my spheres red and blue?
See my source code below for more information:
import bpy
import numpy as np
sizes = { 'In' : 0.7, 'Ga' : 0.7 }
colors = { 'In' : (0.0, 0.0, 255.0, 0.3), 'Ga' : (255.0, 0.4, 0.4, 0.7), 'bond': (0.05, 0.05, 0.05 , 0.1) }
for key in colors.keys():
bpy.data.materials.new(name=key)
bpy.data.materials[key].diffuse_color = colors[key]
bpy.data.materials[key].specular_intensity = 0.1
def distance(a, b):
return np.sqrt(np.dot(a - b, a - b))
def normalize(a):
return np.array(a) / np.sqrt(np.dot(a, a))
class Structure:
def init(self, filename):
with open(filename, 'r') as f:
data = f.readlines()
self.n_atoms = int(data[0].split()[0])
self.atom_list = [line.split()[0] for line in data[2:]]
coordinates = []
for i, line in enumerate(data[2:]):
coordinates.append([float(value) for value in line.split()[1:4]])
self.coordinates = np.array(coordinates)
self.bonds = set()
def add_bonds(self, atom_types, cutoff):
for i in range(self.n_atoms - 1):
position_1 = self.coordinates[i]
element_1 = self.atom_list[i]
if not element_1 in atom_types:
continue
for j in range(i + 1, self.n_atoms):
position_2 = self.coordinates[j]
element_2 = self.atom_list[j]
if not element_2 in atom_types:
continue
dist = distance(position_1, position_2)
if dist <= cutoff:
self.bonds.add((i, j))
def draw_bonds(self):
for atom_1, atom_2 in self.bonds:
pos_1 = self.coordinates[atom_1]
pos_2 = self.coordinates[atom_2]
difference = pos_2 - pos_1
center = (pos_2 + pos_1) / 2.0
magnitude = distance(pos_1, pos_2)
bond_direction = normalize(difference)
vertical = np.array((0.0, 0.0, 1.0))
rotation_axis = np.cross(bond_direction, vertical)
angle = -np.arccos(np.dot(bond_direction, vertical))
bpy.ops.mesh.primitive_cylinder_add(radius=0.1,
depth=magnitude,
location=center)
bpy.context.active_object.data.materials.append(bpy.data.materials['bond'])
bpy.ops.object.shade_smooth()
bpy.ops.transform.rotate(value=angle, axis=rotation_axis)
def draw_atoms(self):
for element, position in zip(self.atom_list, self.coordinates):
bpy.ops.mesh.primitive_uv_sphere_add(radius=sizes[element], location=position)
bpy.context.active_object.data.materials.append(bpy.data.materials[element])
bpy.ops.object.shade_smooth()
def draw_structure(self):
self.draw_atoms()
self.draw_bonds()
InGaN = Structure(r'\8x8x5-xIn=0.5.xyz')
InGaN.draw_structure()