1
$\begingroup$

I am in the process of making a board game, and I need some customized dice.

I need 3, 4, 5, 6, 7, 8, 9, 10, 11 and 12 sided dice for my board game. I have looked around on model sharing websites, and all the models that I could find (free or $$) don't include D5, D7, D9 or D11 dice. So I decided to start modeling my own dice, but I can't figure out how to evenly space the faces/edges on the 7-12 sided dice.

I've been working with Blender for about a few months now, but i still consider myself a novice. I guess I was wondering if there was an easier method to create these dice? I was thinking, maybe to create a sphere with X amount of faces on it, so I tried to use the Ico Sphere option, but it only allows me to edit the subdivisions, not the total face amount. Is there a trick I can do or an add-on that might work well for me here to model these dice accurately?

EDIT: Maybe another alternative would be to create a sphere and then using a boolean modifier, you subtract the desired amount of faces from the sphere leaving behind the desired dice amount? That could work...but the math behind it might be far more sophisticated than what I can do. blender doesnt have a feature that will do this math for me, will it? :P

EDIT 2: I posted this question on the mathematics stack exchange if you guys wanted to go look at it and it's detail. https://math.stackexchange.com/questions/2683018/how-to-evenly-space-out-a-certain-amount-of-axes-off-of-one-center-point

Thank you for your time and response.

~Jared

$\endgroup$
  • $\begingroup$ Related A number of options are covered with add mesh extras. $\endgroup$ – batFINGER Mar 8 '18 at 16:12
  • $\begingroup$ batFINGER - that link is useful, but I'm afraid it really doesn't solve my issue for the d7, d9 or d11 sided dice. still useful though, i will probably use that for the common sided polyhedral objects! $\endgroup$ – Jared J. Mar 8 '18 at 16:54
7
$\begingroup$

Attempt at the D9

enter image description here

The first part of the code, is an algorithm to estimate N equally spaced points on a sphere.

Adapted from

Constructing Polyhedra from Repelling Points on a Sphere

by Simon Tatham

Scatters N points randomly on the surface of a sphere, allows them to move under mutual inverse-square repulsion while keeping them constrained to the sphere's surface, waits until they converge to fixed locations, and outputs their locations.

Once the points are determined to within a tolerance TOL they are rotated to make one the north pole. A 1 radius UV sphere is createdand holes are bisected into the mesh by cutting with a plane normal to the radial of each point, and moved rat along the 1 unit radius.

enter image description here Image showing convex hulls of 9 points on left, and sphere with cutting planes on right.

The Code

Copy the code below, paste in text editor and run script. Change the parameters to suit. Note it might hang every now and then finding a solution , if so hit CtrlC in the system console.

import bpy
import bmesh
from mathutils import Vector
import random
from math import pi, asin, atan2, cos, sin, radians

# parmaaters
n = 9  # number of points on sphere
rat = .86 # how far along the radius to bisect
u_segments = 32  # UV sphere settings
v_segments = 32 
thickness = 0.2  # solidify thickness
TOL = 1e-7

points = [Vector((0, 0, 1))]
for i in range(n - 1):
    theta = random.random() * radians(360)
    phi = 2 * asin(random.random() * 2 - 1)
    points.append(Vector((cos(theta) * cos(phi), 
           sin(theta) * cos(phi), 
           sin(phi))))

while True:
    # Determine the total force acting on each point.
    forces = []
    for i in range(len(points)):
        p = points[i]
        f = Vector()
        ftotal = 0
        for j in range(len(points)):
            if j == i: continue
            q = points[j]
            # Find the distance vector, and its length.
            dv = p - q
            dl = dv.length
            dl3 = dl * dl * dl
            fv = dv / dl3
            # Add to the total force on the point p.
            f = f + fv
        # Stick this in the forces array.
        forces.append(f)
        # Add to the running sum of the total forces/distances.
        ftotal = ftotal + f.length

    fscale = 1 if ftotal <= 0.25 else 0.25 / ftotal

    # Move each point, and normalise. While we do this, also track
    # the distance each point ends up moving.
    dist = 0
    for i in range(len(points)):
        p = points[i]
        f = forces[i]
        p2 = (p + fscale * f).normalized()

        dv = p - p2
        dist = dist + dv.length
        points[i] = p2
    # Done. Check for convergence and finish.
    if dist < TOL: # TOL
        break

context = bpy.context
scene = context.scene
# make one point north pole.
R = points[0].rotation_difference(Vector((0, 0, 1))).to_matrix()
points = [R @ p for p in points]

bm = bmesh.new()
#bmesh.ops.create_icosphere(bm, diameter=1, subdivisions=5 )
bmesh.ops.create_uvsphere(bm, 
        diameter=1, 
        u_segments=u_segments, 
        v_segments=v_segments)

for p in points:
    ret = bmesh.ops.bisect_plane(bm, 
            geom=bm.faces[:]+bm.edges[:]+bm.verts[:],
            plane_co= rat * p,
            plane_no=-p,
            clear_outer=False,
            clear_inner=True)
    '''
    # add visible cutting planes (using bisect)
    R = Vector(p).to_track_quat('Z', 'Y').to_matrix().to_4x4()
    R.translation = rat * p
    bmesh.ops.create_grid(bm, x_segments=1, y_segments=1, size=1, matrix=R)
    '''    
me = bpy.data.meshes.new("dice")
bm.to_mesh(me)
ob = bpy.data.objects.new("dice", me)   
scene.collection.objects.link(ob)
context.view_layer.objects.active = ob
ob.select_set(True)
ob.location = scene.cursor.location
# add a thickness modifier
sm = ob.modifiers.new("Solidify", 'SOLIDIFY')
sm.thickness = thickness

Alternatively could hard code in a set of 9 points.

from mathutils import Vector
raw = [
0.798313857169, -0.442003436215, 0.409057389405,
-0.552293193116, -0.798759837392, 0.238652364346,
-0.173114881688, 0.873088163724, -0.455794137855,
0.749969728716, 0.23229964104, -0.619340199553,
-0.872965308015, 0.388085187337, 0.295502044616,
-0.600669921728, -0.124465371314, -0.789749337749,
0.278179133859, -0.797203763248, -0.535800829925,
-0.105061227491, -0.0758822299659, 0.991566450448,
0.477641726235, 0.744841584279, 0.465907067653
]
it = iter(raw)
points = list(map(Vector, zip(it, it, it)))

EDIT:

Updated for 2.8, for prior version see previous edit revision.

$\endgroup$
  • $\begingroup$ This is fantastic and would presumably work for any number of points. Very well explained too. $\endgroup$ – Rich Sedman Mar 9 '18 at 9:07
  • $\begingroup$ @RichSedman Thanks. Yes does a nice 7. Would like to make it an operator, but the grunt needed to find solution for cases like 9 grinds when sliding props on op panel. Thinking of how to create better topology from the circles. Also been rolling them in the physics engine . $\endgroup$ – batFINGER Mar 9 '18 at 13:25
  • $\begingroup$ i'm sure this is the correct way to make what i want...i just wish i knew how to use code to generate shapes in blender. lol $\endgroup$ – Jared J. Mar 20 '18 at 18:06
  • $\begingroup$ Scratch that, i figured it out. I had no idea you could create shapes using scripts....:O i learned something today, thank you for your help! $\endgroup$ – Jared J. Mar 20 '18 at 20:15
  • $\begingroup$ I learned something, too. But one thing is certain: since it's impossible to make all ridges the same size, this dice would not be a fair one (meaning that not all sides have the same probability) $\endgroup$ – Haunt_House Mar 20 '18 at 23:31
2
$\begingroup$

I'm not confident that you can easily divide a sphere into 7 surfaces. The edge count doesn't really matter for a dice anyway.

Here's a non spherical example for a seven sided dice. It works for all dice between 3 and too many sides. It's basically the way ten sided dice are made.

Create a seven sided cone, not too high, fill type 'Nothing'

enter image description here

In Top View, create a seven sided circle.

Rotate it with R = 360 / 14 RETURN

enter image description here

Shift select your cone, go to Edit Mode and use Knife Project with 'Cut through' checked.

enter image description here

Switch on Vertex Select, invert the selection with CTRLI and delete the 7 verts.

enter image description here

Select the bottom face, put the cursor there, go to Object Mode, Front View, duplicate the cone and rotate it 180° around the cursor. Join them with CTRLJ.

enter image description here

With the lower half selected, go to Top View, use R = 360 / 14 RETURN, whatever that might do.

enter image description here

Select everything, remove doubles and hit F to close the holes, recalc normals.

The result is a 14 sided dice where every bottom face has a parallel face on the top side, so you just have to give the parallel faces the same numbers and you can have uniform dice.

enter image description here

$\endgroup$
  • $\begingroup$ This would solve my problem for sure. thank you for this suggestion. $\endgroup$ – Jared J. Mar 8 '18 at 17:51
  • $\begingroup$ @JaredJ. Repeat my steps, if anything is unclear, I'll expand the answer. $\endgroup$ – Haunt_House Mar 8 '18 at 18:01
1
$\begingroup$

Only certain numbers of faces can exist as a regular solid - some are just not physically possible in three dimensions. The first few regular solids are Tetrahedron (4 faces), Hexahedron (6 faces), Octahedron (8 faces), Dodecahedron (12 faces), Icosahedron (20 faces) so you'll struggle to create the inbetween ones.

That said, there are some ways around this.... for example, you can create a 10-sided solid (a decahedron) but it is not strictly 'regular' (although all faces have the same profile).

For the other numbers of faces you can be creative with the larger regular solids by using multiple faces for the same value.

For example, for a 'D3' you could use a D6 and give the faces values 1, 1, 2, 2, 3, 3.

For D5, use a D10 (irregular) with 1,1,2,2,3,3,4,4,5,5 or a D20 (regular) with 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5.

For D7, you can't create a simple version with a reasonable number of faces... but you could use a D8 and simply re-roll if you get an 8.

D9 is also a challenge..... D10 and re-roll if you get a 10...?

D10 - as an irregular decahedron or use a D20 with 1,1,2,2,3,3,4,4,5,5,...etc...

D11.... D12 with 12 causing a re-roll.

As for how to produce these in Blender, simply enable the Extra Objects addon (in User Preferences, Addon tab). You'll then have additional options in your Add/Mesh menu - in particular Maths Functions/Regular Solids, specifying which solid (4, 6, 8, 12, 20 sided) in the tool shelf (T).

$\endgroup$
  • $\begingroup$ I saw this D9 dice as an example and i'l trying to figure out how to recreate it as a model. upload.wikimedia.org/wikipedia/commons/3/3d/D9_dice.JPG something like that would be adequate enough for me and my board game, but i'm having troubles with the math behind evenly spacing out the hole cutouts. $\endgroup$ – Jared J. Mar 8 '18 at 16:17
  • 1
    $\begingroup$ Try posting on math.stackexchange.com - someone there might be able to advise on spacing. $\endgroup$ – Rich Sedman Mar 8 '18 at 17:18
  • $\begingroup$ Rich, okay. I can do this. thank you for the tip! $\endgroup$ – Jared J. Mar 8 '18 at 17:43
1
$\begingroup$

I'm not sure if this will solve every case, as I have not found a good proof for checking the number of faces vs the number of points, but at any rate, the D9 solution can be found by solving Thompson problem! Now, thanks to tensorflow and Travis Hoppe, we have a math-free answer to that. See 'Stupid Tensorflow Tricks'

Looking at the h5 file found on the associated Github page is straightforward with python:

import h5py

h5 = h5py.File('coordinates.h5','r')
hset = h5['N'] #N is the number of points
coords = hset.get('coordinates')
for item in coords:
    print(item)

This will give you the minimum energy for a certain number of nodes. The D9 case is satisfied by a 7 pointed sphere (N=7).

[0.82112638 0.45593844 0.34332435]
[ 0.70207437 -0.05185188 -0.71021332]
[-0.32175939  0.86663088 -0.38134212]
[-0.19458951  0.33363507  0.92240044]
[-0.94138981 -0.2497393   0.22674989]
[-0.38722143 -0.48798233 -0.78226135]
[ 0.32175939 -0.86663088  0.38134212]

Again, not sure if this will satisfy all of your other cases. If anyone looks at the other cases, please post your findings!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.