2015-03-03 2 views
2

Я пытаюсь сделать это (пустотелый) форму:Линейное и вращательное выдавливание в то же время

funky_shape

Круги на самом деле разные диаметры, и я хотел шею вниз по середине (но это не требование). Я могу подделать форму, рисуя ее поэтапно, но у меня проблемы с ее выпуском, и не похоже, как это делает OpenSCAD (а именно, генерация CSG по часам). Есть ли лучшие способы сделать это? rendered shape:

for(i = [0:180]) { 
    rotate([0,i,0]) 
    translate([26,0,0]) 
    difference() { 
     cylinder(r=10 + (0.083 * i),h=.1); 
     cylinder(r=8 + (0.083 * i),h=.1); 
    } 
} 

ответ

1

первый результат:

difference if 2 polyhedrons

создана разность двух многогранников. 3D-объект действителен, см. «Simple: yes» в консоли

Для получения точек, необходимых для полиэдра, используется python3: сначала создается произвольное количество точек на базовом круге (количество точек определяет разрешение 3D-объекта). Точки вращаются и масштабируются с шагом n до 180 градусов, а конечный масштабный фактор (n также контролирует разрешение). Затем используются точки, чтобы определить грани формы. Наконец, все написано в opencad-синтаксисе в файл.

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 

import math 

# define parameters 
rr = 26      # radius of rotation 
r1 = 10      # outer radius of tube      
r2 = 8      # inner radius of tube 
scale = 2     # scalefactor over rotation 
segments = 90    # segments of base circle -> resolution 
rAngle = 180    # angle of rotation 
rSegments = 45    # segments of rotation  -> resolution 

def polyhedron(rr,radius,scale, segments, rAngle, rSegments): 
    stepAngle = 360/segments 
    rotAngle = rAngle/rSegments 
    points = '['    # string with the vector of point-vectors 
    faces = '['     # string with the vector of face-vectors 
    sprs = (scale-1)/rSegments     # scale per rSegment 

    # construct all points 
    for j in range(0,rSegments+1): 
     angle = j*rotAngle 
     for i in range(0,segments): 
      xflat = (math.sin(math.radians(i*stepAngle))*radius)   # x on base-circle 
      xscaled = xflat*(1 + sprs*j) + rr      # x scaled (+ rr -> correction of centerpoint 
      xrot = math.cos(math.radians(angle))*xscaled    # x rotated 
      yflat = (math.cos(math.radians(-i*stepAngle))*radius)   # y on base-circle 
      yscaled = yflat*(1 + sprs*j)      # y scaled 
      z = math.sin(math.radians(angle))*xscaled     # z rotated 
      string = '[{},{},{}],'.format(xrot,yscaled,z) 
      points += string 

    points += ']' 

    # construct all faces 
    # bottom 
    f = '[' 
    for i in range(segments-1,-1,-1): 
     f += '{},'.format(i) 
    f += '],' 
    faces += f     # add bottom to faces 

    # all faces on the side of the tube 
    for p in range(0, segments*rSegments): 
     p1 = p 
     p2 = p + 1 -segments if p%segments == segments-1 else p +1 
     p3 = p + segments 
     p4 = p3 + 1 -segments if p%segments == segments-1 else p3 +1 
     f = '[{},{},{}],'.format(p1,p4,p3) 
     faces += f 
     f = '[{},{},{}],'.format(p1,p2,p4) 
     faces += f 
    # top 
    f = '[' 
    for i in range(segments*rSegments,segments*(rSegments+1)): 
     f += '{},'.format(i) 
    f += ']' 
    faces += f     # add top to faces 
    faces += ']' 

    string = 'polyhedron(points = {}, faces = {});'.format(points,faces) 
    return string  

# output in openscad-file 
wobj = open('horn.scad','w')   # open openscad-file for writing 
wobj.write('difference() {\n') 
string = ' ' 
string += polyhedron(rr,r1,scale,segments,rAngle,rSegments) 
string += '\n' 
wobj.write(string) 
string = ' ' 
string += polyhedron(rr,r2,scale,segments,rAngle,rSegments) 
string += '\n' 
wobj.write(string) 
wobj.write('}') 
wobj.close()      # close openscad-file 
# finally open openscad-file in openscad 

он оказывает в 34 секунд

+0

Ха-ха, это удивительно умное решение. Рассмотрение OpenSCAD как компоновщика вместо компилятора. –

+0

вот почему мне нравится opencad. И поскольку многогранник является примитивом openscad, его внутренняя открытая капля :-) –

3

Вот чисто openscad версия. См. scad-utils и list-comprehension-demos для получения более подробной информации о модулях и их использовании.

use <scad-utils/transformations.scad> 
use <scad-utils/shapes.scad> 
use <skin.scad> 

fn=32; 
$fn=60; 

r1 = 25; 
r2 = 10; 
R = 40; 
th = 2; 

module tube() 
{ 
    difference() 
    { 
     skin([for(i=[0:fn]) 
       transform(rotation([0,180/fn*i,0])*translation([-R,0,0]), 
         circle(r1+(r1-r2)/fn*i))]); 
     assign(r1 = r1-th, r2 = r2-th) 
     skin([for(i=[0:fn]) 
       transform(rotation([0,180/fn*i,0])*translation([-R,0,0]), 
         circle(r1+(r1-r2)/fn*i))]); 
    } 
} 

tube(); 

result

Смежные вопросы