disdyakis development

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
User avatar
symbolicM
Posts: 18
Joined: Thu Oct 04, 2018 6:44 pm

disdyakis development

Post by symbolicM »



The disdyakis dodecahedron is at the heart of Paul D Burley’s book the Sacred Sphere and matches the biblically described properties of the Ark.

I design to lend its form to a greenhouse that is capable of floating in the event of a flood or worse.
I like to think of it as a Cossac bio-domicile. I’m a long way off from that goal but this is the reason I decided to teach myself FreeCAD.

I’ve made a number of attempts at re-producing this Catalan solid and met with some success but I can’t help but think that there are superior ways to achieve a result. Maybe deductive booleans from a solid, I don’t know, I did not get what I was looking for when I attempted that.

I’ve tried to use the surface workbench (0.19) to “skin” the attached frame of interlaced sketches but have come to the conclusion that this tool was not designed for that purpose.

My question is how would you produce a disdyakis dodecahedron in FreeCAD?
https://infogalactic.com/info/Disdyakis_dodecahedron
Attachments
solid_surface.FCStd
(37.81 KiB) Downloaded 21 times
___
ordinary by design
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: disdyakis development

Post by TheMarkster »

It's a long video, but might be of some interest.

https://www.youtube.com/watch?v=lwI8ZXX-v2w
Snip macro screenshot-cb5590.png
Snip macro screenshot-cb5590.png (40.76 KiB) Viewed 1362 times
User avatar
symbolicM
Posts: 18
Joined: Thu Oct 04, 2018 6:44 pm

Re: disdyakis development

Post by symbolicM »

Thanks for that.
If I understand correctly I should be able to switch my construction sketches to blue - reference mode - and use them to generate a datum plane on which to sketch a scalene triangle and repeat until complete.
I'll give it a go.

Salute for the insight.
___
ordinary by design
chrisb
Veteran
Posts: 53939
Joined: Tue Mar 17, 2015 9:14 am

Re: disdyakis development

Post by chrisb »

The blue construction lines aren't visible outside of Sketcher, and thus cannot be used for creating a DatumPlane. However, you can use a normal sketch for that; if you don't use it for feature generation, it doesn't have the usual restrictions such as no crossings or T-joins.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
edwilliams16
Veteran
Posts: 3112
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: disdyakis development

Post by edwilliams16 »

Once you have the coordinates of the vertices, it's just work... I made a sketch representing stereographic projection
Screen Shot 2021-07-15 at 2.05.23 PM.png
Screen Shot 2021-07-15 at 2.05.23 PM.png (85.72 KiB) Viewed 1281 times
Screen Shot 2021-07-15 at 2.10.57 PM.png
Screen Shot 2021-07-15 at 2.10.57 PM.png (35.63 KiB) Viewed 1281 times

Inverting that gave the coordinates of the vertices. I got bored after creating the edges. Creating wires, then faces look to be very tedious. Given the coordinates, there has to be a much quicker way to generate the solid - maybe the convex hull of the points.

Anyhow the following code in the python console generates the coordinates and the wireframe from the file below with just the sketch.

Code: Select all


def stereo(xyVector, sphereRadius):
    ''' return the inverse stereographic projection of the xy=plane vector xyVector to a sphere radius sphereRadius'''
    x = xyVector.x
    y = xyVector.y
    factor = sphereRadius / (x * x + y * y + sphereRadius * sphereRadius)
    return App.Vector(factor * 2* sphereRadius*x, factor * 2*sphereRadius* y,  factor * (x * x + y * y - sphereRadius*sphereRadius))

sk = App.ActiveDocument.getObject('Sketch')
skg = sk.Geometry
i = 0
vertices = []
points = [ p for p in skg if p.TypeId == 'Part::GeomPoint']
radius = sk.Constraints[20].Value
for p in points:
    vertex = stereo(App.Vector(p.X, p.Y, 0), radius)
    vertices.append(vertex)
    #print(f' {i} : ({p.X}, {p.Y})  {vertex}')
    i += 1

allvertices =[App.Vector(0.,0, -radius), App.Vector(0,0, radius) ]
rot90 = App.Rotation(App.Vector(0, 0, 1), 90)
rot180 = App.Rotation(App.Vector(0, 0, 1), 180)
rot270= App.Rotation(App.Vector(0, 0, 1), 270)
for v in vertices:
    vx = v.x
    vy = v.y
    vz = v.z
    V = App.Vector(vx, vy, vz)
    allvertices.extend([V, rot90.multVec(V), rot180.multVec(V), rot270.multVec(V)])

i=0
pva =[]
for v in allvertices:
    print(v)
    pv =App.ActiveDocument.addObject("Part::Vertex","dydVertex"+str(i))
    pv.X = v.x
    pv.Y = v.y
    pv.Z = v.z
    pva.append(pv)

for i in range(2,6):
    Part.show(Part.makeLine(allvertices[1],allvertices[i]))

for i in range(14,18):
    Part.show(Part.makeLine(allvertices[1],allvertices[i]))

for i in range(10,14):
    Part.show(Part.makeLine(allvertices[0],allvertices[i]))

for i in range(22,26):
    Part.show(Part.makeLine(allvertices[0],allvertices[i]))

for i in range(0,4):
    Part.show(Part.makeLine(allvertices[2+i],allvertices[14+i]))
    Part.show(Part.makeLine(allvertices[10+i],allvertices[22+i]))
    Part.show(Part.makeLine(allvertices[10+i],allvertices[6+i]))
    Part.show(Part.makeLine(allvertices[6+i],allvertices[14+i]))
    Part.show(Part.makeLine(allvertices[22+i],allvertices[18+i]))
    Part.show(Part.makeLine(allvertices[18+i],allvertices[2+i]))
    Part.show(Part.makeLine(allvertices[18+i],allvertices[6+i]))
    Part.show(Part.makeLine(allvertices[22+i],allvertices[10+(i+1)%4]))
    Part.show(Part.makeLine(allvertices[18+i],allvertices[6+(i+1)%4]))
    Part.show(Part.makeLine(allvertices[2+i],allvertices[14+(i+1)%4]))
    Part.show(Part.makeLine(allvertices[6+i],allvertices[2+i])) #
    Part.show(Part.makeLine(allvertices[6+i],allvertices[2+(i-1)%4])) #
    Part.show(Part.makeLine(allvertices[6+i],allvertices[22+ i])) #
    Part.show(Part.makeLine(allvertices[6+i],allvertices[22+(i-1)%4])) #
   
Here are the 26 vertices if someone else wants to construct the object

Code: Select all

Vector (0.0, 0.0, -100.0)
Vector (0.0, 0.0, 100.0)
Vector (57.73502691896254, 57.73502691896249, 57.73502691896271)
Vector (-57.735026918962475, 57.735026918962554, 57.73502691896271)
Vector (-57.73502691896255, -57.73502691896248, 57.73502691896271)
Vector (57.735026918962475, -57.735026918962554, 57.73502691896271)
Vector (100.0, 2.484506934232031e-14, 0.0)
Vector (-2.640608849817178e-15, 100.0, 0.0)
Vector (-100.0, -1.2598601350846777e-14, 0.0)
Vector (2.640608849817178e-15, -100.0, 0.0)
Vector (70.71067811865505, 0.0, -70.71067811865446)
Vector (1.5700924586837817e-14, 70.71067811865505, -70.71067811865446)
Vector (-70.71067811865505, 8.65956056235497e-15, -70.71067811865446)
Vector (-1.5700924586837817e-14, -70.71067811865505, -70.71067811865446)
Vector (70.71067811865471, 0.0, 70.71067811865481)
Vector (1.5700924586837742e-14, 70.71067811865471, 70.71067811865481)
Vector (-70.71067811865471, 8.659560562354928e-15, 70.71067811865481)
Vector (-1.5700924586837742e-14, -70.71067811865471, 70.71067811865481)
Vector (70.71067811865477, 70.71067811865474, 0.0)
Vector (-70.71067811865473, 70.71067811865478, 0.0)
Vector (-70.71067811865478, -70.71067811865473, 0.0)
Vector (70.71067811865473, -70.71067811865478, 0.0)
Vector (57.73502691896248, 57.735026918962525, -57.73502691896274)
Vector (-57.73502691896251, 57.7350269189625, -57.73502691896274)
Vector (-57.73502691896249, -57.73502691896252, -57.73502691896274)
Vector (57.73502691896251, -57.7350269189625, -57.73502691896274)
You actually only need to create a 45 degree wedge about the z-axis. One reflection and a fourfold polar-pattern would finish it (within common face errors). Entertaining construction...
Attachments
dydakis.FCStd
(7.11 KiB) Downloaded 22 times
Screen Shot 2021-07-15 at 2.12.37 PM.png
Screen Shot 2021-07-15 at 2.12.37 PM.png (20.78 KiB) Viewed 1281 times
edwilliams16
Veteran
Posts: 3112
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: disdyakis development

Post by edwilliams16 »

Screen Shot 2021-07-15 at 3.45.55 PM.png
Screen Shot 2021-07-15 at 3.45.55 PM.png (28.51 KiB) Viewed 1263 times
Gave up on the scripting - used Part|ShapeBuilder to make a shell and a solid.
Attachments
dydakis2.FCStd
(233.67 KiB) Downloaded 25 times
edwilliams16
Veteran
Posts: 3112
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: disdyakis development

Post by edwilliams16 »

Well, this isnt quite right. It is close. It took me a while to figure out why. The area is correct, but the volume is wrong and so are the side lengths. Id wrongly assumed that the vertices lay on a sphere, which they don’t quite, so the stereographic projection (at least only one) is not enough to reconstruct the solid.
Fun while it lasted…
edwilliams16
Veteran
Posts: 3112
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: disdyakis development

Post by edwilliams16 »

To learn some Topological data scripting https://wiki.freecadweb.org/Topological_data_scripting I constructed the disdyakis dodecahedron from vertex data in netlib http://www.netlib.org/polyhedra/37 For some strange reason, the data was translated and rotation in some fashion. Anyhow, this method works, though I would have preferred a purely geometric construction.
Screen Shot 2021-07-17 at 3.11.26 PM.png
Screen Shot 2021-07-17 at 3.11.26 PM.png (22.05 KiB) Viewed 1137 times

Code: Select all

'''  Create a Disdyakis dodecahedron from vertex data'''
import Part
from math import sqrt


scaleFactor = 1.0  # =1 => middle edge length =1

#data from http://www.netlib.org/polyhedra/37  https://en.wikipedia.org/wiki/Disdyakis_dodecahedron
#these vertices are tilted and translated for no obvious reason

vertices = [
    App.Vector(2.6133122279038238, -4.3663082302150226, -7.140305645693695),
    App.Vector(2.8343891236796766, -5.0800291876449795, -7.163837801596551),
    App.Vector(2.8419869679386627, -4.0977146372750205, -6.4812216553007066),  # -X
    App.Vector(2.886667096895415, -5.0456133045766546, -6.1657984433994139),  
    App.Vector(3.009894100904886, -4.0067697532409839, -7.6621114168954244),   #+ Z
    App.Vector(3.1604567932353163, -4.8973184004605509, -8.091359576603294),   
    App.Vector(3.1728458528068138, -3.2955543914174693, -6.9782843659031492),  
    App.Vector(3.3382971302138604, -5.6314377767564596, -7.1346547570869689),   # -Y
    App.Vector(3.3513947319758703, -3.9380673488691023, -5.9579217083010231),
    App.Vector(3.6408427234443935, -3.7812913170646378, -7.9936075282074776),   
    App.Vector(3.6831062016314853, -5.5655035406455466, -6.4746655586534303),
    App.Vector(3.6907040458918208, -4.5831889902828067, -5.7920494123621763),    
    App.Vector(3.8510133346080949, -5.4745586566032474, -7.655555320247756),
    App.Vector(3.8662090231277648, -3.5099295558781736, -6.2903230276597041),
    App.Vector(4.0265183118308238, -4.4012992222023037, -8.1538289355476461),
    App.Vector(4.0341161560950081, -3.4189846718394306, -7.4712127892567944),
    App.Vector(4.0763796342737318, -5.2031968954186892, -5.952270819699509),   
    App.Vector(4.3658276257560316, -5.046420863604471, -7.9879566396081482),
    App.Vector(4.3789252275208671, -3.3530504357319652, -6.8112235908168941),   #+Y
    App.Vector(4.544376504923661, -5.6889338210650479, -6.9675939820056528),  
    App.Vector(4.5567655644914461, -4.0871698120259693, -5.8545187713067436),   
    App.Vector(4.7073282568126512, -4.9777184592536349, -6.283766931010124),    #- Z
    App.Vector(4.83055526083214, -3.9388749079095933, -7.7800799045112476),       
    App.Vector(4.8752353897887335, -4.8867735752081337, -7.4646566926071458),   #+X
    App.Vector(4.8828332340508313, -3.904459024847932, -6.7820405463160945),
    App.Vector(5.1039101298205366, -4.6181799822850979, -6.8055727022155921)]

# vertices making up faces
#  No_of vertices (3), vertex_index, vertex_index, vertex_index  indices offset by 50 in data table  i.e 50 -> vertices[0]
vlist =[
    (3, 52, 56, 50),
    (3, 50, 56, 54),
    (3, 54, 55, 50),
    (3, 50, 55, 51),
    (3, 51, 53, 50),
    (3, 50, 53, 52),
    (3, 65, 72, 59),
    (3, 59, 72, 64),
    (3, 64, 55, 59),
    (3, 59, 55, 54),
    (3, 54, 56, 59),
    (3, 59, 56, 65),
    (3, 73, 69, 67),
    (3, 67, 69, 62),
    (3, 62, 55, 67),
    (3, 67, 55, 64),
    (3, 64, 72, 67),
    (3, 67, 72, 73),
    (3, 60, 53, 57),
    (3, 57, 53, 51),
    (3, 51, 55, 57),
    (3, 57, 55, 62),
    (3, 62, 69, 57),
    (3, 57, 69, 60),
    (3, 60, 69, 66),
    (3, 66, 69, 71),
    (3, 71, 70, 66),
    (3, 66, 70, 61),
    (3, 61, 53, 66),
    (3, 66, 53, 60),
    (3, 73, 72, 75),
    (3, 75, 72, 74),
    (3, 74, 70, 75),
    (3, 75, 70, 71),
    (3, 71, 69, 75),
    (3, 75, 69, 73),
    (3, 65, 56, 68),
    (3, 68, 56, 63),
    (3, 63, 70, 68),
    (3, 68, 70, 74),
    (3, 74, 72, 68),
    (3, 68, 72, 65),
    (3, 52, 53, 58),
    (3, 58, 53, 61),
    (3, 61, 70, 58),
    (3, 58, 70, 63),
    (3, 63, 56, 58),
    (3, 58, 56, 52)]


faceList = []
def makeFacesVlist(edgeList, start = 50):
    tList =edgeList[1:4]
    eeList =[]
    for i in range(3):
        jstart = tList[i] -start
        jend = tList[(i+1)%3] - start
        #print (f'{jstart} {jend}')
        edge = Part.Edge(Part.LineSegment(vertices[jstart], vertices[jend]))
        ee = App.ActiveDocument.addObject("Part::Feature", "Edge") 
        ee.Shape = edge
        eeList.append(edge)
        added = eobj.addObject(ee)    
    #print(eeList)
    App.ActiveDocument.recompute()
    w = Part.Wire(eeList)
    face = Part.Face(w)
    ff = App.ActiveDocument.addObject("Part::Feature", "Face")
    ff.Shape = face
    added = fobj.addObject(ff)
    faceList.append(ff.Shape)

#find rotation and translation to orient the object on the z-axis, center at origin 
xhat = (vertices[23] - vertices[2]).normalize()
yhat = (vertices[18] - vertices[7]).normalize()
zhat = (vertices[4] - vertices[21]).normalize()
rot = App.Rotation(xhat, yhat, zhat).inverted()
center = App.Vector(0., 0., 0.)
for v in vertices:
    center = center + v

center = center/len(vertices)
vertices_cen = [ v - center for v in vertices]  #center on origin
vertices_rot = [scaleFactor*rot.multVec(v) for v in vertices_cen]  #scale and rotate
print(f'Circumradius = {((vertices_rot[4] - vertices_rot[21])/2).Length}')
print(f'Edge Lengths {(vertices_rot[2]-vertices_rot[6]).Length}  {(vertices_rot[6]-vertices_rot[0]).Length}  {(vertices_rot[0]-vertices_rot[2]).Length}')
#print(f'Edge Lengths {(vertices_rot[14]-vertices_rot[5]).Length}  {(vertices_rot[5]-vertices_rot[9]).Length}  {(vertices_rot[9]-vertices_rot[14]).Length}')
shortestEdgeLength =  (vertices_rot[0]-vertices_rot[2]).Length

vertices = vertices_rot 
eobj = App.ActiveDocument.addObject("App::DocumentObjectGroup","EdgeGroup")
fobj = App.ActiveDocument.addObject("App::DocumentObjectGroup","FaceGroup")
vobj = App.ActiveDocument.addObject("App::DocumentObjectGroup","VertexGroup")
pva=[]
#create vertices
for v in vertices:
    pv =App.ActiveDocument.addObject("Part::Vertex","Vertex")
    added = vobj.addObject(pv)
    pv.X = v.x
    pv.Y = v.y
    pv.Z = v.z
    pva.append(pv)

#create edges and faces
for edge in vlist:
    makeFacesVlist(edge)

#make solid
solid = Part.Solid(Part.Shell(faceList))
solidobj = App.ActiveDocument.addObject("Part::Feature", "Disdyakis dodecahedron")
solidobj.Shape= solid
App.ActiveDocument.recompute()
#check some parameters
print(f'Volume = {solidobj.Shape.Volume}  Area = {solidobj.Shape.Area}')
print(f'Volume_theory {shortestEdgeLength**3*sqrt(3*(2194 + 1513*sqrt(2)))/7}  Area_theory {shortestEdgeLength**2*sqrt(783+ 436*sqrt(2))*6/7}')
There's a whole database of exotic regular solids in netlib. With some effort one could parse the datafiles and construct any of them in FreeCAD.
Attachments
polyfromvertices.FCStd
(220.59 KiB) Downloaded 22 times
Screen Shot 2021-07-17 at 3.19.32 PM.png
Screen Shot 2021-07-17 at 3.19.32 PM.png (20.56 KiB) Viewed 1137 times
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: disdyakis development

Post by mario52 »

Hi

just for info :

Macro_Polyhedrons Image

Macro_Pyramid Image

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
edwilliams16
Veteran
Posts: 3112
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: disdyakis development

Post by edwilliams16 »

More user interface on those Macros - but nothing quite as exotic as this polyhedron.

Turning code into reality, I 3D printed one. The image shows it sitting on a dodecahedral box I made as an exercise in compound angle cutting. I was testing out a broken Festool Kapex saw I was given, which I rebuilt.
IMG_0952_1.jpg
IMG_0952_1.jpg (945.78 KiB) Viewed 979 times
Post Reply