- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在过去的几天里,我对使用基于编程语言的软件创建 3D 模型的想法产生了兴趣。我一直在玩的一种语言是 OpenSCAD,事实证明它对创建有趣的形状非常有帮助。
我目前正在尝试使用 OpenSCAD 创建一朵花,我遇到了一个问题,我无法使用我在网上找到的文档或其他资源来规避。
这里是问题的简短形式:
我可以将函数作为参数传递给 OpenSCAD 模块吗?
如果可以,怎么做?如果没有,为什么不,我可以做什么?
这让我想到了问题的长篇形式,并针对我的情况进行了详细说明:
我正在尝试使用 2D 极坐标函数的线性拉伸(stretch)来创建花瓣,并将其与 3D 函数相交。
为此,我从在 http://spolearninglab.com/curriculum/lessonPlans/hacking/resources/software/3d/openscad/openscad_math.html 上找到的两个非常好的模块开始.我并没有声称自己一开始就写了它们。
首先 - Dan Newman 的 3D 绘图仪/* 3Dplot.scad */
// 3dplot -- the 3d surface generator
// x_range -- 2-tuple [x_min, x_max], the minimum and maximum x values
// y_range -- 2-tuple [y_min, y_max], the minimum and maximum y values
// grid -- 2-tuple [grid_x, grid_y] indicating the number of grid cells along the x and y axes
// z_min -- Minimum expected z-value; used to bound the underside of the surface
// dims -- 2-tuple [x_length, y_length], the physical dimensions in millimeters
//Want to pass in z(x,y) as parameter
module 3dplot(x_range=[-10, +10], y_range=[-10,10], grid=[50,50], z_min=-5, dims=[80,80]){
dx = ( x_range[1] - x_range[0] ) / grid[0];
dy = ( y_range[1] - y_range[0] ) / grid[1];
// The translation moves the object so that its center is at (x,y)=(0,0)
// and the underside rests on the plane z=0
scale([dims[0]/(max(x_range[1],x_range[0])-min(x_range[0],x_range[1])),
dims[1]/(max(y_range[1],y_range[0])-min(y_range[0],y_range[1])),1])
translate([-(x_range[0]+x_range[1])/2, -(y_range[0]+y_range[1])/2, -z_min])
union()
{
for ( x = [x_range[0] : dx : x_range[1]] )
{
for ( y = [y_range[0] : dy : y_range[1]] )
{
polyhedron(points=[[x,y,z_min], [x+dx,y,z_min], [x,y,z(x,y)], [x+dx,y,z(x+dx,y)],
[x+dx,y+dy,z_min], [x+dx,y+dy,z(x+dx,y+dy)]],
faces=prism_faces_1);
polyhedron(points=[[x,y,z_min], [x,y,z(x,y)], [x,y+dy,z_min], [x+dx,y+dy,z_min],
[x,y+dy,z(x,y+dy)], [x+dx,y+dy,z(x+dx,y+dy)]],
faces=prism_faces_2);
}
}
}
}
第二个 - 2D Grapher/* 2dgraphing.scad */
// function to convert degrees to radians
function d2r(theta) = theta*360/(2*pi);
// These functions are here to help get the slope of each segment, and use that to find points for a correctly oriented polygon
function diffx(x1, y1, x2, y2, th) = cos(atan((y2-y1)/(x2-x1)) + 90)*(th/2);
function diffy(x1, y1, x2, y2, th) = sin(atan((y2-y1)/(x2-x1)) + 90)*(th/2);
function point1(x1, y1, x2, y2, th) = [x1-diffx(x1, y1, x2, y2, th), y1-diffy(x1, y1, x2, y2, th)];
function point2(x1, y1, x2, y2, th) = [x2-diffx(x1, y1, x2, y2, th), y2-diffy(x1, y1, x2, y2, th)];
function point3(x1, y1, x2, y2, th) = [x2+diffx(x1, y1, x2, y2, th), y2+diffy(x1, y1, x2, y2, th)];
function point4(x1, y1, x2, y2, th) = [x1+diffx(x1, y1, x2, y2, th), y1+diffy(x1, y1, x2, y2, th)];
function polarX(theta) = cos(theta)*r(theta);
function polarY(theta) = sin(theta)*r(theta);
module nextPolygon(x1, y1, x2, y2, x3, y3, th) {
if((x2 > x1 && x2-diffx(x2, y2, x3, y3, th) < x2-diffx(x1, y1, x2, y2, th) || (x2 <= x1 && x2-diffx(x2, y2, x3, y3, th) > x2-diffx(x1, y1, x2, y2, th)))) {
polygon(
points = [
point1(x1, y1, x2, y2, th),
point2(x1, y1, x2, y2, th),
// This point connects this segment to the next
point4(x2, y2, x3, y3, th),
point3(x1, y1, x2, y2, th),
point4(x1, y1, x2, y2, th)
],
paths = [[0,1,2,3,4]]
);
}
else if((x2 > x1 && x2-diffx(x2, y2, x3, y3, th) > x2-diffx(x1, y1, x2, y2, th) || (x2 <= x1 && x2-diffx(x2, y2, x3, y3, th) < x2-diffx(x1, y1, x2, y2, th)))) {
polygon(
points = [
point1(x1, y1, x2, y2, th),
point2(x1, y1, x2, y2, th),
// This point connects this segment to the next
point1(x2, y2, x3, y3, th),
point3(x1, y1, x2, y2, th),
point4(x1, y1, x2, y2, th)
],
paths = [[0,1,2,3,4]]
);
}
else {
polygon(
points = [
point1(x1, y1, x2, y2, th),
point2(x1, y1, x2, y2, th),
point3(x1, y1, x2, y2, th),
point4(x1, y1, x2, y2, th)
],
paths = [[0,1,2,3]]
);
}
}
module 2dgraph(bounds=[-10,10], th=2, steps=10, polar=false, parametric=false) {
step = (bounds[1]-bounds[0])/steps;
union() {
for(i = [bounds[0]:step:bounds[1]-step]) {
if(polar) {
nextPolygon(polarX(i), polarY(i), polarX(i+step), polarY(i+step), polarX(i+2*step), polarY(i+2*step), th);
}
else if(parametric) {
nextPolygon(x(i), y(i), x(i+step), y(i+step), x(i+2*step), y(i+2*step), th);
}
else {
nextPolygon(i, f(i), i+step, f(i+step), i+2*step, f(i+2*step), th);
}
}
}
}
我的包装代码:
include <2dgraphing.scad>;
include <3dplot.scad>;
function z(x,y) = pow(x,2)+pow(y,2); //function used in 3dplot
function r(theta) = cos(4*theta); //function used in 2dgraph
module Petals () {
difference () {
union () { //everything to add
intersection () {
3dplot([-4,4],[-4,4],[50,50],-2.5);
scale([20, 20, 20]) linear_extrude(height=0.35)
2dgraph([0, 720], 0.1, steps=160, polar=true);
}
}
union () { //everything to subtract
}
}
}
Petals();
当我渲染世界上计算成本最高的花瓣时,世界一切都很好,花花公子。
[在这里我会发布一张图片,但由于这是我的第一篇文章,我没有先决条件 10 点声望]
但是,现在我想从花瓣底部减去多余部分。因此,我可以使用具有更陡函数和更低起点的 3D 图,并从原始 3D 图中减去它。
所以在同一个程序中,我想使用两个不同的函数来实现 3Dplot 模块的两种不同用途。
我尝试修改 3dplot 和我的代码来这样做:
Modified 3dplot:
module 3dplot(x_range=[-10, +10], y_range=[-10,10], grid=[50,50], z_min=-5, dims=[80,80], input_function)
{
dx = ( x_range[1] - x_range[0] ) / grid[0];
dy = ( y_range[1] - y_range[0] ) / grid[1];
// The translation moves the object so that its center is at (x,y)=(0,0)
// and the underside rests on the plane z=0
scale([dims[0]/(max(x_range[1],x_range[0])-min(x_range[0],x_range[1])),
dims[1]/(max(y_range[1],y_range[0])-min(y_range[0],y_range[1])),1])
translate([-(x_range[0]+x_range[1])/2, -(y_range[0]+y_range[1])/2, -z_min])
union()
{
for ( x = [x_range[0] : dx : x_range[1]] )
{
for ( y = [y_range[0] : dy : y_range[1]] )
{
polyhedron(points=[[x,y,z_min], [x+dx,y,z_min], [x,y,input_function(x,y)], [x+dx,y,input_function(x+dx,y)],
[x+dx,y+dy,z_min], [x+dx,y+dy,input_function(x+dx,y+dy)]],
faces=prism_faces_1);
polyhedron(points=[[x,y,z_min], [x,y,input_function(x,y)], [x,y+dy,z_min], [x+dx,y+dy,z_min],
[x,y+dy,input_function(x,y+dy)], [x+dx,y+dy,input_function(x+dx,y+dy)]],
faces=prism_faces_2);
}
}
}
}
修改了我的代码:
include <2dgraphing.scad>;
include <3dplot.scad>;
function z1(x,y) = pow(x,2)+pow(y,2); //function used in 3dplot
function z2(x,y) = pow(pow(x,2)+pow(y,2),1.5)-1; //function to be subtracted out
function r(theta) = cos(4*theta); //function used in 2dgraph
module Petals () {
difference () {
union () { //everything to add
intersection () {
3dplot([-4,4],[-4,4],[50,50],-2.5);
scale([20, 20, 20]) linear_extrude(height=0.35)
2dgraph([0, 720], 0.1, steps=160, polar=true, input_function=z1);
}
}
union () { //everything to subtract
3dplot([-4,4],[-4,4],[50,50],-2.5,input_function=z2);
}
}
}
Petals();
我收到以下错误:警告:忽略未知函数“input_function”。
那么我该如何着手将函数作为参数传递呢?
在此之前我没有用任何函数式语言编写过,但我从 OpenSCAD 用户手册中了解到“从 2015.03 版开始,现在可以在任何范围内分配变量。”所以我应该能够为 3dplot 的每次运行更改 input_function 的值,就像 3dplot 中的变量一样。我是不是理解错了?
作为一个可选的附带问题:OpenSCAD 是否有明确的方法来实现我当前的目标,而不会在渲染过程中产生大量计算负载?
我已经花了足够多的时间来尝试解决这个问题,所以我发布了这个冗长的问题,如果我对一个简单的现有解决方案感到困惑,我深表歉意。我非常感谢任何愿意提供帮助的人。
最佳答案
目前无法将函数作为参数传递。同时生成大量小对象(例如 3dplot 模块中的多面体)会使模型渲染非常慢。为了这特定用例还有其他选项来生成模型。
最新的 OpenSCAD 版本提供的新列表生成功能允许基于函数生成单个多面体。
参见 3d-functions.scad在演示存储库中。这plots这函数 f(x, y)。
关于STL - 如何将函数作为参数传递给 OpenSCAD 模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34275683/
有没有办法将 STL 文件导入 OpenSCAD 并能够修改它们? 例如,以下代码演示了我迄今为止的尝试: difference() { import("spherical_puzzle_ba
我是 openscad 的新手,并试图从 dxf 文件制作 3d 模型。我想将其大小指定为 130x130。我已经能够得到下面的代码,但它仍然没有断言我想要的大小: linear_extrude(he
我注意到 OpenSCAD 文档没有阐明术语“对象” 和“节点” 是否指的是同一事物。对象是 defined作为“积木”,“由 2D 和 3D 基元创建”并以分号结尾 另一方面 nodes由变换操作(
我在 OpenScad 中的 If 语句有问题。 我有 4 个变量 a=20; b=14; w=1; c=16; 我想查一下女巫号是否更大a或 b . 然后根据谁较小来获取较小变量的值(在我们的例子中
是否有一种简单的方法/功能来为openscad对象倒圆角? e.g. round the edges of the cylinders 最佳答案 minkowski() 是您的 friend ,可以对
我正在尝试绘制这个(空心)形状: 这些圆圈实际上是不同的直径,我想像这样在连接管的中间缩颈(但这不是必需的)。我可以通过逐段绘制来伪造形状,但我在缩颈时遇到了问题,而且感觉不像 OpenSCAD 想要
以下代码围绕原点旋转第二个立方体。如何围绕其中心点([5,5,0])旋转第二个立方体? cube([10,10,1]); rotate([0,0,45]) cube([10,10,1]); 最佳答案
我是 OpenSCAD 的新手,遇到了一个我不明白的问题。在以下代码段中,变量“ofs”不是从“for”迭代的先前值累积的。 slots = [5, 7, 11, 17]; ofs = 0; for
我是 OpenSCAD 的新手,遇到了一个我不明白的问题。在以下代码段中,变量“ofs”不是从“for”迭代的先前值累积的。 slots = [5, 7, 11, 17]; ofs = 0; for
openscad 是否有任何用于字符串键控关联数组的语言原语(又名 HashMap ,又名字典)?或者是否有任何关于如何模拟关联数组的约定? 到目前为止,我所能想到的就是使用向量并使用变量将索引映射到
OpenSCAD 输出的透明度可以通过添加 % 来实现到元素,但这不允许将透明元素放在具有更高透明度(例如,以百分比表示)的周围元素中,并且可以在透明元素内看到透明元素中的(不透明)元素。怎么做? 最
我在任意位置有两个对象,我想在一个和另一个之间绘制一个圆柱体。搜索数学解决方案告诉我我需要点积和叉积分别作为角度和轴,但是我无法生成四元数或将结果转换为 rotate 的参数。 . 这是我到目前为止:
我不小心遗漏了翻译向量中的方括号。 OpenSCAD 没有引发错误,而是默默地忽略了该错误。 带有多个参数的translate()有什么特殊含义吗?第二行应该做什么?我附上了一张显示我得到的结果的图片
openScad上有类似的东西吗? list = [2, 3]; if(1 in list){ echo("in"); }else{ echo("not in"); } /* or bette
在过去的几天里,我对使用基于编程语言的软件创建 3D 模型的想法产生了兴趣。我一直在玩的一种语言是 OpenSCAD,事实证明它对创建有趣的形状非常有帮助。 我目前正在尝试使用 OpenSCAD 创建
在 OpenSCAD 中,我希望能够创建一个 module接受 string然后创建一个 3-D 对象,将该字符串作为 text 嵌入表面中。 .我希望对象比 text 稍大,所以我需要知道 text
我经常尝试连接不同的点以在 OpenScad 中绘制 直线。但我找不到任何方法来画线。但我可以画出确定的形状,如立方体、球体、圆柱体等......所以请指导我进入正确的程序编码,通过连接不同的点来绘制
我不小心遗漏了翻译向量中的方括号。 OpenSCAD 没有引起错误,而是默默地忽略了错误。 有多个参数的translate()有什么特殊含义吗?第二行应该做什么?我附上了一张图片,显示了我得到的结果。
我怎样才能弯曲一张纸(立方体)?我想控制弯曲/曲线的角度。 例如 立方体([50,50,2]); 最佳答案 您可以 rotate_extrude()一个带有参数角的矩形。这需要 openscad 版本
我试图在 Windows 7 中通过命令提示符运行 OpenScad。但是我无法让它工作。我将以下目录添加到路径 "C:\Program Files\OpenSCAD\" 并尝试运行以下脚本: fro
我是一名优秀的程序员,十分优秀!