ruby-gr 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/gr/ffi.rb CHANGED
@@ -8,7 +8,7 @@ module GR
8
8
 
9
9
  begin
10
10
  ffi_lib GR.ffi_lib
11
- rescue LoadError => e
11
+ rescue LoadError
12
12
  raise LoadError, 'Could not find GR Framework'
13
13
  end
14
14
 
@@ -47,7 +47,7 @@ module GR
47
47
  attach_function :gr_setmarkertype, %i[int], :void
48
48
  attach_function :gr_inqmarkertype, %i[pointer], :void
49
49
  attach_function :gr_setmarkersize, %i[double], :void
50
- # gr_inqmarkersize is not implemented.
50
+ attach_function :gr_inqmarkersize, %i[pointer], :void
51
51
  attach_function :gr_setmarkercolorind, %i[int], :void
52
52
  attach_function :gr_inqmarkercolorind, %i[pointer], :void
53
53
  attach_function :gr_settextfontprec, %i[int int], :void
@@ -126,16 +126,16 @@ module GR
126
126
  attach_function :gr_setarrowstyle, %i[int], :void
127
127
  attach_function :gr_setarrowsize, %i[double], :void
128
128
  attach_function :gr_drawarrow, %i[double double double double], :void
129
- # attach_function :gr_readimage, %i[pointer pointer pointer pointer], :int
129
+ attach_function :gr_readimage, %i[string pointer pointer pointer], :int
130
130
  attach_function :gr_drawimage, %i[double double double double int int pointer int], :void
131
- # attach_function :gr_importgraphics, %i[string], :int
131
+ attach_function :gr_importgraphics, %i[string], :int
132
132
  attach_function :gr_setshadow, %i[double double double], :void
133
133
  attach_function :gr_settransparency, %i[double], :void
134
134
  attach_function :gr_setcoordxform, %i[pointer], :void
135
135
  attach_function :gr_begingraphics, %i[string], :void
136
136
  attach_function :gr_endgraphics, %i[], :void
137
- # attach_function :gr_getgraphics
138
- # attach_function :gr_drawgraphics
137
+ attach_function :gr_getgraphics, %i[], :string
138
+ attach_function :gr_drawgraphics, %i[string], :int
139
139
  attach_function :gr_mathtex, %i[double double string], :void
140
140
  attach_function :gr_inqmathtex, %i[double double string pointer pointer], :void
141
141
  attach_function :gr_beginselection, %i[int int], :void
@@ -151,14 +151,14 @@ module GR
151
151
  attach_function :gr_selectcontext, %i[int], :void
152
152
  attach_function :gr_destroycontext, %i[int], :void
153
153
  attach_function :gr_uselinespec, %i[string], :void
154
- # attach_function :gr_delaunay
154
+ # attach_function :gr_delaunay, %i[int pointer pointer pointer pointer], :void
155
155
  attach_function :gr_reducepoints, %i[int pointer pointer int pointer pointer], :void
156
156
  attach_function :gr_trisurface, %i[int pointer pointer pointer], :void
157
157
  attach_function :gr_gradient, %i[int int pointer pointer pointer pointer pointer], :void
158
158
  attach_function :gr_quiver, %i[int int pointer pointer pointer pointer int], :void
159
- # attach_function :gr_interp2
159
+ attach_function :gr_interp2, %i[int int pointer pointer pointer int int pointer pointer pointer int double], :void
160
160
 
161
- # gr_newmeta
161
+ # attach_function :gr_newmeta
162
162
  # attach_function :gr_deletemeta
163
163
  # attach_function :gr_finalizemeta
164
164
  # attach_function :gr_meta_args_push
@@ -185,6 +185,7 @@ module GR
185
185
  # attach_function :gr_meta_max_plotid
186
186
  # attach_function :gr_dumpmeta
187
187
  # attach_function :gr_dumpmeta_json
188
+
188
189
  attach_function :gr_version, %i[], :pointer
189
190
  attach_function :gr_shadepoints, %i[int pointer pointer int int int], :void
190
191
  attach_function :gr_shadelines, %i[int pointer pointer int int int], :void
data/lib/gr/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GR
4
+ VERSION = GRCommons::VERSION
5
+ end
data/lib/gr3.rb CHANGED
@@ -25,6 +25,7 @@ module GR3
25
25
  end
26
26
 
27
27
  require_relative 'gr_commons'
28
+ require_relative 'gr3/version'
28
29
  require_relative 'gr3/ffi'
29
30
  require_relative 'gr3/gr3base'
30
31
 
@@ -50,50 +51,455 @@ module GR3
50
51
  extend CheckError
51
52
 
52
53
  class << self
54
+ # This method initializes the gr3 context.
55
+ def gr3_init(*)
56
+ super
57
+ end
58
+
59
+ def free(*)
60
+ super
61
+ end
62
+
63
+ # This function terminates the gr3 context.
64
+ def terminate(*)
65
+ super
66
+ end
67
+
68
+ # This function returns information on the most recent GR3 error.
69
+ def geterror(*)
70
+ super
71
+ end
72
+
73
+ # This function allows the user to find out how his commands are rendered.
74
+ def getrenderpathstring(*)
75
+ super
76
+ end
77
+
78
+ # This function returns a string representation of a given error code.
79
+ def geterrorstring(*)
80
+ super
81
+ end
82
+
83
+ # This function clears the draw list.
84
+ def clear(*)
85
+ super
86
+ end
87
+
88
+ def usecurrentframebuffer(*)
89
+ super
90
+ end
91
+
92
+ def useframebuffer(*)
93
+ super
94
+ end
95
+
96
+ def setquality(*)
97
+ super
98
+ end
99
+
100
+ # getimage
101
+ def getimage(width, height, use_alpha = true)
102
+ bpp = use_alpha ? 4 : 3
103
+ inquiry(uint8: width * height * bpp) do |bitmap|
104
+ super(width, height, (use_alpha ? 1 : 0), bitmap)
105
+ end
106
+ end
107
+
108
+ def export(*)
109
+ super
110
+ end
111
+
112
+ def drawimage(*)
113
+ super
114
+ end
115
+
116
+ # createmesh_nocopy
53
117
  def createmesh_nocopy(_n, vertices, normals, colors)
54
118
  inquiry_int do |mesh|
55
119
  super(mesh, vertices, normals, colors)
56
120
  end
57
121
  end
58
122
 
123
+ # This function creates a int from vertex position, normal and color data.
59
124
  def createmesh(_n, vertices, normals, colors)
60
125
  inquiry_int do |mesh|
61
126
  super(mesh, vertices, normals, colors)
62
127
  end
63
128
  end
64
129
 
130
+ # This function creates a mesh from vertex position, normal and color data.
65
131
  def createindexedmesh_nocopy(num_vertices, vertices, normals, colors, num_indices, indices)
66
132
  inquiry_int do |mesh|
67
133
  super(mesh, num_vertices, vertices, normals, colors, num_indices, indices)
68
134
  end
69
135
  end
70
136
 
137
+ # This function creates a int from vertex position, normal and color data.
71
138
  def createindexedmesh(num_vertices, vertices, normals, colors, num_indices, indices)
72
139
  inquiry_int do |mesh|
73
140
  super(mesh, num_vertices, vertices, normals, colors, num_indices, indices)
74
141
  end
75
142
  end
76
143
 
77
- def getimage(width, height, use_alpha = true)
78
- bpp = use_alpha ? 4 : 3
79
- inquiry(uint8: width * height * bpp) do |bitmap|
80
- super(width, height, (use_alpha ? 1 : 0), bitmap)
81
- end
144
+ # This function adds a mesh to the draw list, so it will be drawn when the user calls gr3_getpixmap.
145
+ def drawmesh(*)
146
+ super
147
+ end
148
+
149
+ # This function marks a mesh for deletion and removes the user’s reference from the mesh’s referenc counter,
150
+ # so a user must not use the mesh after calling this function.
151
+ def deletemesh(*)
152
+ super
153
+ end
154
+
155
+ # This function sets the view matrix by getting the position of the camera,
156
+ # the position of the center of focus and the direction which should point up.
157
+ def cameralookat(*)
158
+ super
159
+ end
160
+
161
+ # This function sets the projection parameters.
162
+ def setcameraprojectionparameters(*)
163
+ super
164
+ end
165
+
166
+ # Get the projection parameters.
167
+ def getcameraprojectionparameters(*)
168
+ super
169
+ end
170
+
171
+ # This function sets the direction of light.
172
+ def setlightdirection(*)
173
+ super
174
+ end
175
+
176
+ # This function sets the background color.
177
+ def setbackgroundcolor(*)
178
+ super
179
+ end
180
+
181
+ def createheightmapmesh(*)
182
+ super
183
+ end
184
+
185
+ def drawheightmap(*)
186
+ super
82
187
  end
83
188
 
84
- # gr3_gr
189
+ def drawconemesh(*)
190
+ super
191
+ end
85
192
 
193
+ def drawcylindermesh(*)
194
+ super
195
+ end
196
+
197
+ def drawspheremesh(*)
198
+ super
199
+ end
200
+
201
+ def drawcubemesh(*)
202
+ super
203
+ end
204
+
205
+ def setobjectid(*)
206
+ super
207
+ end
208
+
209
+ def selectid(*)
210
+ super
211
+ end
212
+
213
+ def getviewmatrix(*)
214
+ super
215
+ end
216
+
217
+ def setviewmatrix(*)
218
+ super
219
+ end
220
+
221
+ def getprojectiontype(*)
222
+ super
223
+ end
224
+
225
+ def setprojectiontype(*)
226
+ super
227
+ end
228
+
229
+ # This function creates an isosurface from voxel data using the
230
+ # marching cubes algorithm.
231
+ # Returns a mesh.
232
+ def createisosurfacemesh(grid, step, offset, isolevel)
233
+ dim_x, dim_y, dim_z = grid.shape
234
+ step_x, step_y, step_z = step
235
+ offset_x, offset_y, offset_z = offset
236
+ # NArray does not have the strides method
237
+ bytesize = grid.class.byte_size
238
+ stride_x = 1
239
+ stride_y = dim_y
240
+ stride_z = dim_y * dim_z
241
+ # stride_x, stride_y, stride_z = stride
242
+ inquiry_int do |mesh|
243
+ super(mesh, uint16(grid), isolevel, dim_x, dim_y, dim_z,
244
+ stride_x, stride_y, stride_z, step_x, step_y, step_z, offset_x, offset_y, offset_z)
245
+ end
246
+ end
247
+
248
+ # Create a mesh of a surface plot similar to gr_surface.
86
249
  def createsurfacemesh(nx, ny, px, py, pz, option = 0)
87
250
  inquiry_int do |mesh|
88
251
  super(mesh, nx, ny, px, py, pz, option)
89
252
  end
90
253
  end
91
254
 
92
- # gr3_convenience
255
+ # Draw a mesh with the projection of gr.
256
+ def drawmesh_grlike(*)
257
+ super
258
+ end
93
259
 
260
+ # Convenience function for drawing a surfacemesh.
261
+ def drawsurface(*)
262
+ super
263
+ end
264
+
265
+ # Create a surface plot with gr3 and draw it with gks as cellarray.
266
+ def surface(px, py, pz, _option)
267
+ nx = px.length
268
+ ny = py.length
269
+ # TODO: Check out_of_bounds
270
+ super(nx, ny, px, py, pz, ption)
271
+ end
272
+
273
+ # drawtubemesh
94
274
  def drawtubemesh(n, points, colors, radii, num_steps = 10, num_segments = 20)
95
275
  super(n, points, colors, radii, num_steps, num_segments)
96
276
  end
277
+
278
+ # createtubemesh
279
+ def createtubemesh(n, points, colors, radii, num_steps = 10, num_segments = 20)
280
+ inquiry_uint do |mesh| # mesh should be Int?
281
+ super(mesh, n, points, colors, radii, num_steps, num_segments)
282
+ end
283
+ end
284
+
285
+ # drawspins
286
+ def drawspins(positions, directions, colors = nil,
287
+ cone_radius = 0.4, cylinder_radius = 0.2,
288
+ cone_height = 1.0, cylinder_height = 1.0)
289
+ n = positions.length
290
+ colors = [1] * n * 3 if colors.nil?
291
+ super(n, positions, directions, colors, cone_radius, cylinder_radius, cone_height, cylinder_height)
292
+ end
293
+
294
+ # drawmolecule
295
+ def drawmolecule(positions, colors = nil, radii = nil, spins = nil,
296
+ bond_radius = nil, bond_color = nil, bond_delta = nil,
297
+ set_camera = true, rotation = 0, tilt = 0)
298
+ # Should `drawmolecule` take keyword arguments?
299
+ # Setting default values later for now.
300
+
301
+ # Should it be RubyArray instead of Narray?
302
+ # If NArray is required, add no NArray error.
303
+ positions = Numo::SFloat.cast(positions)
304
+ n = positions.shape[0]
305
+
306
+ colors = if colors.nil?
307
+ Numo::SFloat.ones(n, 3)
308
+ else
309
+ Numo::SFloat.cast(colors).reshape(n, 3)
310
+ end
311
+
312
+ radii = if radii.nil?
313
+ Numo::SFloat.new(n).fill(0.3)
314
+ else
315
+ Numo::SFloat.cast(radii).reshape(n)
316
+ end
317
+
318
+ bond_color ||= [0.8, 0.8, 0.8]
319
+ bond_color = Numo::SFloat.cast(bond_color).reshape(3)
320
+ bond_delta ||= 1.0
321
+ bond_radius ||= 0.1
322
+
323
+ if set_camera
324
+ deg2rad = ->(degree) { degree * Math::PI / 180 } # room for improvement
325
+ cx, cy, cz = *positions.mean(axis: 0)
326
+ dx, dy, dz = *positions.ptp(axis: 0)
327
+ d = [dx, dy].max / 2 / 0.4142 + 3
328
+ r = dz / 2 + d
329
+ rx = r * Math.sin(deg2rad.call(tilt)) * Math.sin(deg2rad.call(rotation))
330
+ ry = r * Math.sin(deg2rad.call(tilt)) * Math.cos(deg2rad.call(rotation))
331
+ rz = r * Math.cos(deg2rad.call(tilt))
332
+ ux = Math.sin(deg2rad.call(tilt + 90)) * Math.sin(deg2rad.call(rotation))
333
+ uy = Math.sin(deg2rad.call(tilt + 90)) * Math.cos(deg2rad.call(rotation))
334
+ uz = Math.cos(deg2rad.call(tilt + 90))
335
+ cameralookat(cx + rx, cy + ry, cz + rz, cx, cy, cz, ux, uy, uz)
336
+ setcameraprojectionparameters(45, d - radii.max - 3, d + dz + radii.max + 3)
337
+ end
338
+
339
+ super(n, positions, colors, radii, bond_radius, bond_color, bond_delta)
340
+
341
+ if spins
342
+ spins = Numo::SFloat.cast(spins).reshape(n, 3)
343
+ drawspins(positions, spins, colors)
344
+ end
345
+ end
346
+
347
+ # Creates meshes for slices through the given data, using the current GR
348
+ # colormap. Use the parameters x, y or z to specify what slices should be
349
+ # drawn and at which positions they should go through the data. If neither
350
+ # x nor y nor z are set, 0.5 will be used for all three.
351
+ # Returns meshes for the yz-slice, the xz-slice and the xy-slice.
352
+ def createslicemeshes(grid, x = nil, y = nil, z = nil, step = nil, offset = nil)
353
+ if [x, y, z].all?(&:nil?)
354
+ x = 0.5
355
+ y = 0.5
356
+ z = 0.5
357
+ end
358
+ _mesh_x = (createxslicemesh(grid, x, step, offset) if x)
359
+ _mesh_y = (createyslicemesh(grid, y, step, offset) if y)
360
+ _mesh_z = (createzslicemesh(grid, z, step, offset) if z)
361
+ [_mesh_x, _mesh_y, _mesh_z]
362
+ end
363
+
364
+ def preprocess_createslicemesh(grid, step, offset)
365
+ # TODO: raise error when grid is not narray
366
+ # grid
367
+ case grid.class::MAX
368
+ when Integer
369
+ input_max = grid.class::MAX
370
+ when Float
371
+ # floating point values are expected to be in range [0, 1]
372
+ # Complex narrays are not taken into account
373
+ input_max = 1
374
+ grid[grid > 1] = 1
375
+ else
376
+ raise ArgumentError, 'grid must be three dimensional array of Real numbers'
377
+ end
378
+ scaling_factor = Numo::UInt16::MAX / input_max.to_f
379
+ grid = (grid.cast_to(Numo::UInt64) * scaling_factor).cast_to(Numo::UInt16) # room for improvement
380
+
381
+ # step & offset
382
+ nx, ny, nz = grid.shape
383
+ if step.nil? && offset.nil?
384
+ step = [2.0 / (nx - 1), 2.0 / (ny - 1), 2.0 / (nz - 1)]
385
+ offset = [-1.0, -1.0, -1.0]
386
+ elsif offset.nil?
387
+ offset = [-step[0] * (nx - 1) / 2.0,
388
+ -step[1] * (ny - 1) / 2.0,
389
+ -step[2] * (nz - 1) / 2.0]
390
+ elsif step.nil?
391
+ step = [-offset[0] * 2.0 / (nx - 1),
392
+ -offset[1] * 2.0 / (ny - 1),
393
+ -offset[2] * 2.0 / (nz - 1)]
394
+ end
395
+
396
+ step_x, step_y, step_z = step
397
+ offset_x, offset_y, offset_z = offset
398
+
399
+ [grid, nx, ny, nz, step_x, step_y, step_z, offset_x, offset_y, offset_z]
400
+ end
401
+
402
+ # Creates a meshes for a slices through the yz-plane of the given data,
403
+ # using the current GR colormap. Use the x parameter to set the position of
404
+ # the yz-slice.
405
+ # Returns a mesh for the yz-slice.
406
+ def createxslicemesh(grid, x = 0.5, step = nil, offset = nil)
407
+ grid, nx, ny, nz, step_x, step_y, step_z, offset_x, offset_y, offset_z = preprocess_createslicemesh(grid, step, offset)
408
+ x = (x.clamp(0, 1) * nx).floor
409
+ stride_x = 1
410
+ stride_y = ny
411
+ stride_z = ny * nz
412
+ inquiry_int do |mesh|
413
+ super(mesh, grid, x, nx, ny, nz, stride_x, stride_y, stride_z,
414
+ step_x, step_y, step_z, offset_x, offset_y, offset_z)
415
+ end
416
+ end
417
+
418
+ # Creates a meshes for a slices through the xz-plane of the given data,
419
+ # using the current GR colormap. Use the y parameter to set the position of
420
+ # the xz-slice.
421
+ # Returns a mesh for the xz-slice.
422
+ def createyslicemesh(grid, y = 0.5, step = nil, offset = nil)
423
+ grid, nx, ny, nz, step_x, step_y, step_z, offset_x, offset_y, offset_z = preprocess_createslicemesh(grid, step, offset)
424
+ y = (y.clamp(0, 1) * ny).floor
425
+ stride_x = nx
426
+ stride_y = 1
427
+ stride_z = nx * nz
428
+ inquiry_int do |mesh|
429
+ super(mesh, grid, y, nx, ny, nz, stride_x, stride_y, stride_z,
430
+ step_x, step_y, step_z, offset_x, offset_y, offset_z)
431
+ end
432
+ end
433
+
434
+ # Creates a meshes for a slices through the xy-plane of the given data,
435
+ # using the current GR colormap. Use the z parameter to set the position of
436
+ # the xy-slice.
437
+ # Returns a mesh for the xy-slice.
438
+ def createzslicemesh(grid, z = 0.5, step = nil, offset = nil)
439
+ grid, nx, ny, nz, step_x, step_y, step_z, offset_x, offset_y, offset_z = preprocess_createslicemesh(grid, step, offset)
440
+ z = (z.clamp(0, 1) * nz).floor
441
+ stride_x = ny * nz
442
+ stride_y = ny
443
+ stride_z = 1
444
+ inquiry_int do |mesh|
445
+ super(mesh, grid, z, nx, ny, nz, stride_x, stride_y, stride_z,
446
+ step_x, step_y, step_z, offset_x, offset_y, offset_z)
447
+ end
448
+ end
449
+
450
+ # Draw a yz-slice through the given data, using the current GR colormap.
451
+ def drawxslicemesh(grid, x = 0.5, step = nil, offset = nil,
452
+ position = [0, 0, 0], direction = [0, 0, 1], up = [0, 1, 0],
453
+ color = [1, 1, 1], scale = [1, 1, 1])
454
+ mesh = createxslicemesh(grid, x, step, offset)
455
+ drawmesh(mesh, 1, position, direction, up, color, scale)
456
+ deletemesh(mesh)
457
+ end
458
+
459
+ # Draw a xz-slice through the given data, using the current GR colormap.
460
+ def drawyslicemesh(grid, y = 0.5, step = nil, offset = nil,
461
+ position = [0, 0, 0], direction = [0, 0, 1], up = [0, 1, 0],
462
+ color = [1, 1, 1], scale = [1, 1, 1])
463
+ mesh = createyslicemesh(grid, y, step, offset)
464
+ drawmesh(mesh, 1, position, direction, up, color, scale)
465
+ deletemesh(mesh)
466
+ end
467
+
468
+ # Draw a xy-slice through the given data, using the current GR colormap.
469
+ def drawzslicemesh(grid, z = 0.5, step = nil, offset = nil,
470
+ position = [0, 0, 0], direction = [0, 0, 1], up = [0, 1, 0],
471
+ color = [1, 1, 1], scale = [1, 1, 1])
472
+ mesh = createzslicemesh(grid, z, step, offset)
473
+ drawmesh(mesh, 1, position, direction, up, color, scale)
474
+ deletemesh(mesh)
475
+ end
476
+
477
+ # raw slices through the given data, using the current GR colormap.
478
+ # Use the parameters x, y or z to specify what slices should be drawn and at
479
+ # which positions they should go through the data. If neither x nor y nor
480
+ # z are set, 0.5 will be used for all three.
481
+ def drawslicemeshes(grid, x = nil, y = nil, z = nil, step = nil,
482
+ offset = nil, position = [0, 0, 0], direction = [0, 0, 1], up = [0, 1, 0],
483
+ color = [1, 1, 1], scale = [1, 1, 1])
484
+ meshes = createslicemeshes(grid, x, y, z, step, offset)
485
+ meshes.each do |mesh|
486
+ if mesh
487
+ drawmesh(mesh, 1, position, direction, up, color, scale)
488
+ deletemesh(mesh)
489
+ end
490
+ end
491
+ end
492
+
493
+ def volume(data, algorithm)
494
+ inquiry %i[double double] do |dmin, dmax|
495
+ amin.write_double(-1)
496
+ dmax.write_double(-1)
497
+ # TODO: raise error when no NArray
498
+ data = Numo::DFloat.cast(data) if data.is_a Array
499
+ nx, ny, nz = data.shape
500
+ super(nx, ny, nz, data, algorithm, dmin, dmax)
501
+ end
502
+ end
97
503
  end
98
504
 
99
505
  # Constants - imported from GR.jl
@@ -134,4 +540,94 @@ module GR3
134
540
  SURFACE_GRTRANSFORM = 4
135
541
  SURFACE_GRCOLOR = 8
136
542
  SURFACE_GRZSHADED = 16
543
+
544
+ ATOM_COLORS =
545
+ [[0, 0, 0],
546
+ [255, 255, 255], [217, 255, 255], [204, 128, 255],
547
+ [194, 255, 0], [255, 181, 181], [144, 144, 144],
548
+ [48, 80, 248], [255, 13, 13], [144, 224, 80],
549
+ [179, 227, 245], [171, 92, 242], [138, 255, 0],
550
+ [191, 166, 166], [240, 200, 160], [255, 128, 0],
551
+ [255, 255, 48], [31, 240, 31], [128, 209, 227],
552
+ [143, 64, 212], [61, 225, 0], [230, 230, 230],
553
+ [191, 194, 199], [166, 166, 171], [138, 153, 199],
554
+ [156, 122, 199], [224, 102, 51], [240, 144, 160],
555
+ [80, 208, 80], [200, 128, 51], [125, 128, 176],
556
+ [194, 143, 143], [102, 143, 143], [189, 128, 227],
557
+ [225, 161, 0], [166, 41, 41], [92, 184, 209],
558
+ [112, 46, 176], [0, 255, 0], [148, 255, 255],
559
+ [148, 224, 224], [115, 194, 201], [84, 181, 181],
560
+ [59, 158, 158], [36, 143, 143], [10, 125, 140],
561
+ [0, 105, 133], [192, 192, 192], [255, 217, 143],
562
+ [166, 117, 115], [102, 128, 128], [158, 99, 181],
563
+ [212, 122, 0], [148, 0, 148], [66, 158, 176],
564
+ [87, 23, 143], [0, 201, 0], [112, 212, 255],
565
+ [255, 255, 199], [217, 225, 199], [199, 225, 199],
566
+ [163, 225, 199], [143, 225, 199], [97, 225, 199],
567
+ [69, 225, 199], [48, 225, 199], [31, 225, 199],
568
+ [0, 225, 156], [0, 230, 117], [0, 212, 82],
569
+ [0, 191, 56], [0, 171, 36], [77, 194, 255],
570
+ [77, 166, 255], [33, 148, 214], [38, 125, 171],
571
+ [38, 102, 150], [23, 84, 135], [208, 208, 224],
572
+ [255, 209, 35], [184, 184, 208], [166, 84, 77],
573
+ [87, 89, 97], [158, 79, 181], [171, 92, 0],
574
+ [117, 79, 69], [66, 130, 150], [66, 0, 102],
575
+ [0, 125, 0], [112, 171, 250], [0, 186, 255],
576
+ [0, 161, 255], [0, 143, 255], [0, 128, 255],
577
+ [0, 107, 255], [84, 92, 242], [120, 92, 227],
578
+ [138, 79, 227], [161, 54, 212], [179, 31, 212],
579
+ [179, 31, 186], [179, 13, 166], [189, 13, 135],
580
+ [199, 0, 102], [204, 0, 89], [209, 0, 79],
581
+ [217, 0, 69], [224, 0, 56], [230, 0, 46],
582
+ [235, 0, 38], [255, 0, 255], [255, 0, 255],
583
+ [255, 0, 255], [255, 0, 255], [255, 0, 255],
584
+ [255, 0, 255], [255, 0, 255], [255, 0, 255],
585
+ [255, 0, 255]].map! { |i| i.map! { |j| j / 255.0 } }
586
+
587
+ atom_number = {}
588
+ { H: 1, HE: 2, LI: 3, BE: 4, B: 5, C: 6, N: 7,
589
+ O: 8, F: 9, NE: 10, NA: 11, MG: 12, AL: 13,
590
+ SI: 14, P: 15, S: 16, CL: 17, AR: 18, K: 19,
591
+ CA: 20, SC: 21, TI: 22, V: 23, CR: 24, MN: 25,
592
+ FE: 26, CO: 27, NI: 28, CU: 29, ZN: 30, GA: 31,
593
+ GE: 32, AS: 33, SE: 34, BR: 35, KR: 36, RB: 37,
594
+ SR: 38, Y: 39, ZR: 40, NB: 41, MO: 42, TC: 43,
595
+ RU: 44, RH: 45, PD: 46, AG: 47, CD: 48, IN: 49,
596
+ SN: 50, SB: 51, TE: 52, I: 53, XE: 54, CS: 55,
597
+ BA: 56, LA: 57, CE: 58, PR: 59, ND: 60, PM: 61,
598
+ SM: 62, EU: 63, GD: 64, TB: 65, DY: 66, HO: 67,
599
+ ER: 68, TM: 69, YB: 70, LU: 71, HF: 72, TA: 73,
600
+ W: 74, RE: 75, OS: 76, IR: 77, PT: 78, AU: 79,
601
+ HG: 80, TL: 81, PB: 82, BI: 83, PO: 84, AT: 85,
602
+ RN: 86, FR: 87, RA: 88, AC: 89, TH: 90, PA: 91,
603
+ U: 92, NP: 93, PU: 94, AM: 95, CM: 96, BK: 97,
604
+ CF: 98, ES: 99, FM: 100, MD: 101, NO: 102,
605
+ LR: 103, RF: 104, DB: 105, SG: 106, BH: 107,
606
+ HS: 108, MT: 109, DS: 110, RG: 111, CN: 112,
607
+ UUB: 112, UUT: 113, UUQ: 114, UUP: 115, UUH: 116,
608
+ UUS: 117, UUO: 118 }.each do |key, value|
609
+ atom_number[key] = value
610
+ atom_number[key.to_s] = value # allow string keys
611
+ end
612
+ ATOM_NUMBERS = atom_number.freeze
613
+
614
+ ATOM_VALENCE_RADII =
615
+ [0, # Avoid atomic number to index conversion
616
+ 230, 930, 680, 350, 830, 680, 680, 680, 640,
617
+ 1120, 970, 1100, 1350, 1200, 750, 1020, 990,
618
+ 1570, 1330, 990, 1440, 1470, 1330, 1350, 1350,
619
+ 1340, 1330, 1500, 1520, 1450, 1220, 1170, 1210,
620
+ 1220, 1210, 1910, 1470, 1120, 1780, 1560, 1480,
621
+ 1470, 1350, 1400, 1450, 1500, 1590, 1690, 1630,
622
+ 1460, 1460, 1470, 1400, 1980, 1670, 1340, 1870,
623
+ 1830, 1820, 1810, 1800, 1800, 1990, 1790, 1760,
624
+ 1750, 1740, 1730, 1720, 1940, 1720, 1570, 1430,
625
+ 1370, 1350, 1370, 1320, 1500, 1500, 1700, 1550,
626
+ 1540, 1540, 1680, 1700, 2400, 2000, 1900, 1880,
627
+ 1790, 1610, 1580, 1550, 1530, 1510, 1500, 1500,
628
+ 1500, 1500, 1500, 1500, 1500, 1500, 1600, 1600,
629
+ 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600,
630
+ 1600, 1600, 1600, 1600, 1600, 1600].map { |i| i / 1000.0 }
631
+
632
+ ATOM_RADII = ATOM_VALENCE_RADII.map { |i| i * 0.4 }
137
633
  end