Python Stars

July 5, 2019

Stars – First Incantation – Click Image to Load

 

import bpy
import bmesh
import math
import numpy
from mathutils import Matrix

bpyscene = bpy.context.scene

# this script creates the nearest stars as spheres
# they are sorted

# scale factor; it shows how much a.u. are in 1 light year. 
# In reality it's about 66000, but we're doing things cheap here
sc = 1

# this is the star's diameter, also in a.u. as everything else here
siz = 0.1

# making an empty object to represent the equatorial reference frame
def MakeEmpty(Name):
    e = None
    for i in bpy.data.objects:
        if i.name == Name: e = i
    if e == None:
        bpy.ops.object.add(type='EMPTY')
        e = bpy.context.active_object
        e.name = Name
    return(e)

inc = 23.4*math.pi/180
asc = 180*math.pi/180
peri = 180*math.pi/180

MakeEmpty('Equatorial_system')

bpy.context.active_object.select_set(state=True)
obj = bpy.context.active_object

obj.rotation_euler = (obj.rotation_euler.to_matrix() @ Matrix.Rotation(asc, 3, 'Z')).to_euler()
obj.rotation_euler = (obj.rotation_euler.to_matrix() @ Matrix.Rotation(inc, 3, 'X')).to_euler()
obj.rotation_euler = (obj.rotation_euler.to_matrix() @ Matrix.Rotation(peri, 3, 'Z')).to_euler()

# I'm an idiot who doesn't know how to use Euler transformations in Python, 
# despite the evidence above, so I define them manually as a function

def Eul( lon, lat ):
   inc = math.pi/2
   asc = lon*math.pi/180
   peri = lat*math.pi/180
   mat = numpy.array([[math.cos(asc)*math.cos(peri) - math.cos(inc)*math.sin(asc)*math.sin(peri),-math.cos(inc)*math.cos(peri)*math.sin(asc) - math.cos(asc)
*math.sin(peri), math.sin(asc)*math.sin(inc)],
[math.cos(peri)*math.sin(asc) + math.cos(asc)*math.cos(inc)*math.sin(peri), math.cos(asc)*math.cos(inc)*math.cos(peri) - math.sin(asc)*math.sin(peri), -
math.cos(asc)*math.sin(inc)],
[math.sin(inc)*math.sin(peri), math.cos(peri)*math.sin(inc), math.cos(inc)]])
   return mat;

# gimmestar(dist,lon,lat,name) gives you the sphere at a distance dist, 
# [equatorial] logitude and latitude lon and lat, assigns a name "name" to it 
# and links it to the previously created equatorial coordinate system to be displayed properly

def gimmestar(dist,lon,lat,name):

    
    mesh = bpy.data.meshes.new(name)
    barnards_star = bpy.data.objects.new(name, mesh)
    bpy.context.collection.objects.link(barnards_star)
    bpy.context.view_layer.objects.active = barnards_star
    bpy.context.active_object.select_set(state=True)
    bm = bmesh.new()
    bmesh.ops.create_grid(bm, x_segments=2, y_segments=2, size=siz)
    bm.to_mesh(mesh)
    bm.free()
    objects = bpy.data.objects
    a1 = objects[name]
    b1 = objects['Equatorial_system']
    a1.parent = b1
    a1.location = numpy.dot(Eul(lon,lat),(sc*dist, 0, 0))
    return


# I took these from wiki

# 1-10
gimmestar(4.244,217.3,-62.7,"a Centauri")
gimmestar(5.957,269.5,4.68,"Barnard's Star")
gimmestar(6.503,162.3,-53.32,"Luhman 16")
gimmestar(7.26,133.75,-7.23,"WISE 0855-0714")
gimmestar(7.856,164,7.0,"Wolf 359")
gimmestar(8.307,165.75,35.97,"Lalande 21185")
gimmestar(8.659,101.25,-16.7,"Sirius")
gimmestar(8.791,24.75,-17.95,"Luyten 726-8")
gimmestar(9.704,282.25,-23.83,"Ross 154")
gimmestar(10.29,355.25,44.17,"Ross 248")