-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
шестерни с эвольвентой #58
Comments
Решил, что если не выходит с sew, то проще нарисовать шестерню одним циклом ) И вот оно есть:
|
Для полноценной шестерни не хватает скругления на конце и у основания зуба
|
Я сейчас пока в командировке. Позже посмотрю. |
Когда будешь свободен посмотри.
|
Выглядит круто. Я позволил себе немного переписать с использованием инструмента интерполяции и оформить в виде функции: from zencad import *
r = 40 # радиус без зуба
r_zub = 50 # радиус вместе с зубом
N_zub = 20 # количество зубов
x_zub = 2 # толщина конца зуба
def gear_profile(r, r_zub, N_zub, x_zub, n_tochek=20):
"""
r: радиус без зуба
r_zub: радиус вместе с зубом
N_zub: количество зубов
x_zub: толщина конца зуба
n_tochek: количество точек в апроксимации эвольвенты
"""
# Максимальная длинна эвольвенты
alfa = math.sqrt(r_zub**2 - r**2)/r
# Угол дуги окружности, которую занимает эвольвента
omega = math.asin((r*(math.sin(alfa) - alfa*math.cos(alfa)) )/ r_zub)
# Угол дуги окружности, которую занимает зуб
teta = 2*math.pi/N_zub
# Угол смещения второй грани зуба относительно первой
ax = 2*math.asin(x_zub/(2*r_zub))
d = - 2 * omega - ax
#pnts=[]
wires = []
abases = []
bbases = []
for k in range(N_zub):
apnts = []
for j in range(0,n_tochek+1):
a = j*alfa/n_tochek
# Считаем точки эвольвенты первой грани
x = r*(math.cos(a) + a*math.sin(a))
y = r*(math.sin(a) - a*math.cos(a))
# Добавляем точки первой эвольвенты относительно повернутой системы координат
apnts.append([x*math.cos(-k*teta) + y*math.sin(-k*teta),\
-x*math.sin(-k*teta)+y*math.cos(-k*teta)])
bpnts = []
for j in range(n_tochek,0,-1):
a = j*alfa/n_tochek
# Считаем точки эвольвенты второй грани
x = r*(math.cos(a) + a*math.sin(a))
y = -r*(math.sin(a) - a*math.cos(a))
# Добавляем точки второй эвольвенты относительно повернутой системы координат
bpnts.append([x*math.cos(-k*teta +d) + y*math.sin(-k*teta+d),\
-x*math.sin(-k*teta+d)+y*math.cos(-k*teta+d)])
# Создать эвольвентные рёбра зуба
wires.append(interpolate(apnts))
wires.append(interpolate(bpnts))
# Создать рёбро вершины зуба
wires.append(segment(apnts[-1], bpnts[0]))
# Запомнить точки основания зубьев
abases.append(apnts[0])
bbases.append(bpnts[-1])
# Добавляем рёбра между основанием зубьев
wires.append(segment(abases[0], bbases[-1]))
for k in range(N_zub - 1):
wires.append(segment(abases[k+1], bbases[k]))
# Собираем все элементы в единый wire
evolv = sew(wires)
return evolv
m = gear_profile(r, r_zub, N_zub, x_zub).fill()
m = linear_extrude(proto=m, vec=(0,0,10), center=True)
disp(m)
disp(circle(r_zub,wire=True),color.red)
show() Единственное, возможно параметры не совсем те, которые могут ожидаться. Тут скорее всего должен как-то фигурировать модуль шестерни, делительный диаметр и всё такое. Надо понять, какие должны быть входные параметры и можно добавить как стандартный элемент. |
Да... У rounded_polysegment действительно нету параметра closed. Это, пожалуй, даже баг. Скругления в основании добавить стоит ниже профиля эвольвенты (типо проточка). А вот на вершинах зубьев, мне кажется никаких скруглений быть не должно, чтобы не портить рабочую поверхность. Надо подумать, как это можно устроить. polysegment бы использовать нехотелось, он больно ребрист, а интерполированные участки fillet не скругляет :(. |
p.s. Я добавил проточку в основание зуба, но прямо сейчас оно не соберётся, потому что по ходу дела в алгоритме сшивки рёбер обнаружился баг. После обновления можно будет так: from zencad import *
import zencad.geom.ops1d2d
zencad.lazy.fastdo=True
zencad.lazy.decache=False
def gear_profile(r, r_zub, N_zub, x_zub, paz_deep=None, n_tochek=20):
"""
r: радиус без зуба
r_zub: радиус вместе с зубом
N_zub: количество зубов
x_zub: толщина конца зуба
n_tochek: количество точек в апроксимации эвольвенты
"""
# Максимальная длинна эвольвенты
alfa = math.sqrt(r_zub**2 - r**2)/r
# Угол дуги окружности, которую занимает эвольвента
omega = math.asin((r*(math.sin(alfa) - alfa*math.cos(alfa)) )/ r_zub)
# Угол дуги окружности, которую занимает зуб
teta = 2*math.pi/N_zub
# Угол смещения второй грани зуба относительно первой
ax = 2*math.asin(x_zub/(2*r_zub))
d = - 2 * omega - ax
#pnts=[]
wires = []
abases = []
bbases = []
for k in range(N_zub):
apnts = []
for j in range(0,n_tochek+1):
a = j*alfa/n_tochek
# Считаем точки эвольвенты первой грани
x = r*(math.cos(a) + a*math.sin(a))
y = r*(math.sin(a) - a*math.cos(a))
# Добавляем точки первой эвольвенты относительно повернутой системы координат
apnts.append(point3([
x*math.cos(-k*teta) + y*math.sin(-k*teta),\
-x*math.sin(-k*teta)+y*math.cos(-k*teta)
]))
bpnts = []
for j in range(n_tochek,0,-1):
a = j*alfa/n_tochek
# Считаем точки эвольвенты второй грани
x = r*(math.cos(a) + a*math.sin(a))
y = -r*(math.sin(a) - a*math.cos(a))
# Добавляем точки второй эвольвенты относительно повернутой системы координат
bpnts.append(point3([
x*math.cos(-k*teta +d) + y*math.sin(-k*teta+d),\
-x*math.sin(-k*teta+d)+y*math.cos(-k*teta+d)
]))
# Создать эвольвентные рёбра зуба
wires.append(interpolate(apnts))
wires.append(interpolate(bpnts))
# Создать рёбро вершины зуба
wires.append(segment(apnts[-1], bpnts[0]))
# Запомнить точки основания зубьев
abases.append(apnts[0])
bbases.append(bpnts[-1])
if paz_deep is None:
# Добавляем рёбра между основанием зубьев
wires.append(segment(abases[0], bbases[-1]))
for k in range(N_zub - 1):
wires.append(segment(abases[k+1], bbases[k]))
else:
# Добавляем проточку между основанием зубьев
scl = scale((r_zub-paz_deep)/r_zub)
abases2 = [ scl(a) for a in abases ]
bbases2 = [ scl(b) for b in bbases ]
wires.append(rounded_polysegment(r=paz_deep,
pnts=[abases[0], abases2[0], bbases2[-1], bbases[-1]]))
for k in range(N_zub-1):
wires.append(rounded_polysegment(r=paz_deep,
pnts=[abases[k+1], abases2[k+1], bbases2[k], bbases[k]]))
evolv = sew(wires)
return evolv
m = gear_profile(r=40, r_zub=50, N_zub=20, x_zub=2, paz_deep=1).fill()
m = linear_extrude(proto=m, vec=(0,0,10), center=True)
disp(m)
disp(circle(50,wire=True),color.red)
show() |
к слову, circle() очень криво выглядит. Двумерные фигуры нельзя представлять в виде границ, только полигогами? |
Да, я тоже замечал. Это особенность работы 3д рендера. Он принципиально полигональный. Наверное можно где-то настройку точности подкрутить. Надо будет посмотреть. |
Я подкрутил отображение кривых, теперь они более гладкие. Они всё еще полигональные, но мой глаз уже не раздрожает. И добавил настроечку, которая влияет на разрешение. |
Я (наконец-то! ) построил по точкам шестеренку через модуль и количество зубьев.
|
Выглядит неплохо. |
Привет.
Хотел я запилить тебе шестеренки с эвольвентой
вот такие
но в последний момент, когда хочу объединить всю фигуру через sew() получается что-то странное
не могу понять что
там, где m = c должно быть m = sew(c)
The text was updated successfully, but these errors were encountered: