Wrap an image around a cylinder

扶醉桌前 提交于 2020-01-15 06:13:29

问题


Someone asked me recently if I could print a bracelet with a custom image engraved on its side.

To me, the problem is simple: I have a 2d cartesian system (x,y) that expresses the points of the vectorized image the person sent me. I want to treat these as a 3d cylindrical system (theta, r, z') where r is constant. Finally, I want to convert this 3d cylindrical system to a 3d cartesian system (x',y',z') in the usual way.

So:

z' = y
y' = r cos(x)
x' = r sin(x)

The problem is I don't know how to express this to OpenSCAD. There is an option for matrix transformation using multmatrix(), but this only allows for linear transformation - i.e. I can't express things like cos(x), at least to my knowledge.

What I want is either:

  • an existing module/hack to express this transformation, or

  • a generic method for performing per-vertex transformations, much like a vertex shader in glsl

At very least, is it possible to confirm such things are not available in OpenSCAD?


回答1:


you can use surface(), see http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Surface. Calculate the heightmap in an external script and write the values in a file, e.g. 'surface.dat'. you can translate and rotate the resulting surface and use it in difference().

I tried it with this code and the 'surface.dat' from documentation

difference() {
translate([0,0,5])cube([10,10,10], center =true);
rotate([0,0,90])surface(file = "surface.dat", center = true, convexity = 5);}

edit 28.10.2014: in another way you can use pixeldata in a matrix to place pixel by pixel on the circumference of the bracelet by a for loop and iteration over the matrix. The vectors in the matrix contain pixel(x), pixel(y) and the greyvalue/255 as dimension for depth of engraving. To reduce the number of shapes the pixels of one column can be pooled, creating a polygon representing the depth-profile of this column and linear-extrude it. In this case the vectors contain the pixel(x) and the pointmatrix of the polygon. I tried it successfully with the known graphic of Che. To generate the matrix i use python3.4, PyQt5 and Qt.QtGui.QImage. By default openscad turns off rendering at 2000 elements. You can set it to the needed number under Edit/Preferences/Advanced

the openscad-script:

include <./matrix_p.scad>;
difference() {
    translate([-b,0,0]) rotate([0,90,0]) difference() {
        cylinder(h = hb, r = rb, center = false);
        translate([0,0,-0.5]) cylinder(h = hb+1, r = rb-tb, center = false);
    } 
    for (val = m)
    rotate([-ap*val[0],0,0]) translate([0,-rb-0.1,-ps/2]) linear_extrude(height = ps) polygon(points = val[1]);
}

parameter set in matrix_p.scad:

// userinput
rb = 50;                    //radius bracelet
tb = 5;                     //thickness of b.
hb = 80;                    //height of b.
b = 10;                     //borderwidth beside engraving
// input from Qt.QtGui.QImage
iw = 590;                   //imagewidth in pixel
ih = 726;                    //height in pixel
ps = (hb-2*b)/ih;           //scaling of pixel to fill the free place
ap = (ps*180)/(PI*rb);      //angle per pixel

Download all scripts



来源:https://stackoverflow.com/questions/26489828/wrap-an-image-around-a-cylinder

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!