2012-02-22 39 views
3

我最近一直在尋找Zonohedrons和Rob Bell做出了美麗的。我玩了免費的Polar Zonohedron Sketchup Plugin,並想到使用Processing來玩幾何。到目前爲止,我已經打開了插件/ Ruby腳本並試圖直接移植它,但是我對Ruby沒有經驗,並且一直在使用Sketchup Ruby API reference處理中呈現極地Zonohedron的問題

代碼的幾何部分主要是在polar_zonohedron功能:

def polar_zonohedron #frequency, pitch = atan(sqrt(2)/2), len = 1.0 # frequency,pitch,length 

    mo = Sketchup.active_model 
    mo.start_operation "polar_zonohedron" 

    prompts = ["Frequency", "Pitch in radians", "Length"] 
    values = [8, "atan(sqrt(2)/2)", 12.inch] 
    results = inputbox prompts, values, "Polar Zonohedron" 

    return if not results # This means that the user canceld the operation 

    ents = mo.active_entities 
    grp = ents.add_group 
    ents = grp.entities 

    grp.frequency = results[0] 
    grp.pitch = eval(results[1]) 
    grp.length = results[2] 

    pts=[] 

    #we begin by setting pts[0] to the origin 
    pts[0] = Geom::Point3d.new(0,0,0) 

    vector = Geom::Vector3d.new(cos(grp.pitch),0,sin(grp.pitch)) #tilt pitch vector up the xz plane 
    vector.length = grp.length 

    #Using the origin as the initial generator we iterate thru each zone of the zonohedron 
    #our first task is to define the four points of the base rhomb for this zone 
    #at the end the pts[3] becomes our new origin for the rhomb of the next zone 
    1.upto(grp.frequency-1){ |i| 
    p_rotate = Geom::Transformation.rotation(pts[0] , Geom::Vector3d.new(0,0,1), i*2*PI/grp.frequency) 

    #obtain the other three points of the rhomb face 
    pts[1] = pts[0].transform vector 
    pts[3] = pts[1].transform(p_rotate) 
    pts[2] = pts[3].transform(vector) 

    #we now have the 4 points which make this zone's base rhomb 
    #so we rotate around the origin frequency times making a star pattern of faces 
    0.upto(grp.frequency-1){ |j| 
     f_rotate = Geom::Transformation.rotation(Geom::Point3d.new(0,0,0) , Geom::Vector3d.new(0,0,1), j*2*PI/grp.frequency)  
     ents.add_face(pts.collect{|p| p.transform(f_rotate)}) 
    } 

    #set the origin for the rhomb of the next zone 
    pts[0] = pts[3] 
    } 

    mo.commit_operation 
end 

我已經理解了環,但我稍微變換困惑:

pts[1] = pts[0].transform vector 
pts[3] = pts[1].transform(p_rotate) 
pts[2] = pts[3].transform(vector) 

至於我可以告訴pts[1]pts[0]vector, 和pts[3]的載體成癮是pts[1]乘以p_rotate旋轉matri X。 pts[2]是否也會添加(在pts[3]vector之間)?

這裏是我的嘗試看起來像至今:

//a port attempt of Rob Bell's polar_zonohedron.rb script - http://zomebuilder.com/ 

int frequency = 3; 
float pitch = atan(sqrt(2)/2); 
float length = 24; 

ArrayList<Face> faces = new ArrayList<Face>(); 

void setup(){ 
    size(400,400,P3D); 
    strokeWeight(3); 
    setupZome(); 
} 
void setupZome(){ 
    faces.clear(); 
    PVector[] pts = new PVector[4]; 
    pts[0] = new PVector(); 

    PVector vector = new PVector(cos(pitch),0,sin(pitch)); 
    vector.mult(length); 

    for(int i = 1 ; i < frequency; i++){ 
    PMatrix3D p_rotate = new PMatrix3D(); 
    p_rotate.rotate(i * TWO_PI/frequency, 0,0,1); 
    //PVector v = new PVector(); 
    //p_rotate.mult(pts[0],v); 
    //pts[0] = v; 

    pts[1] = PVector.add(pts[0],vector); 
    pts[3] = new PVector(); 
    p_rotate.mult(pts[1],pts[3]); 
    pts[2] = PVector.add(pts[3],vector); 

    for(int j = 0; j < frequency; j++){ 
     PMatrix3D f_rotate = new PMatrix3D(); 
     f_rotate.rotate(j*2*PI/frequency , 0,0,1); 

     Face f = new Face(); 
     for(PVector pt : pts){ 
     PVector p = new PVector(); 
     f_rotate.mult(pt,p); 
     f.add(p.get()); 
     } 
     faces.add(f); 
    } 

    pts[0] = pts[3]; 
    } 
} 
void draw(){ 
    background(255); 
    lights(); 

    translate(width * .5, height * .5,0); 
    rotateY(map(mouseX,0,width,-PI,PI)); 
    rotateX(map(mouseY,0,height,-PI,PI)); 
    drawAxes(100); 
    pushMatrix(); 
    translate(0,0,-frequency * length * .25); 
    for(Face f : faces){ 
    beginShape(mousePressed ? QUADS : POINTS); 
     for(PVector p : f.pts) vertex(p.x,p.y,p.z); 
    endShape(); 
    } 
    popMatrix(); 
} 
void keyPressed(){ 
    if(keyCode == UP && frequency < 32) frequency++; 
    if(keyCode == DOWN && frequency > 2) frequency--; 
    setupZome(); 
} 
void drawAxes(int size){ 
    stroke(192,0,0); 
    line(0,0,0,size,0,0); 
    stroke(0,192,0); 
    line(0,0,0,0,size,0); 
    stroke(0,0,192); 
    line(0,0,0,0,0,size); 
} 
class Face{ 
    ArrayList<PVector> pts = new ArrayList<PVector>(); 
    Face(){} 
    void add(PVector p){ 
    if(pts.size() <= 4) pts.add(p); 
    } 
} 

我覺得我很接近,但我得到了循環條件語句和頂點索引錯誤。 有關如何解決此問題的任何提示?

回答

2

我非常接近,但沒有注意所有的細節。 原來我得到正確的網,如果我不增加對p_rotate旋轉:

p_rotate.rotate(TWO_PI/frequency, 0,0,1); 

代替

p_rotate.rotate(i * TWO_PI/frequency, 0,0,1); 

以下是完整的代碼清單:

//a port attempt of Rob Bell's polar_zonohedron.rb script - http://zomebuilder.com/ 

int frequency = 3; 
float pitch = atan(sqrt(2)/2); 
float length = 24; 

ArrayList<Face> faces = new ArrayList<Face>(); 

void setup(){ 
    size(400,400,P3D); 
    strokeWeight(3); 
    setupZome(); 
} 
void setupZome(){ 
    faces.clear(); 
    PVector[] pts = new PVector[4]; 
    pts[0] = new PVector(); 

    PVector vector = new PVector(cos(pitch),0,sin(pitch)); 
    vector.mult(length); 

    for(int i = 1 ; i < frequency-1; i++){ 
    PMatrix3D p_rotate = new PMatrix3D(); 
    p_rotate.rotate(TWO_PI/frequency, 0,0,1); 

    pts[1] = PVector.add(pts[0],vector); 
    pts[3] = new PVector(); 
    p_rotate.mult(pts[1],pts[3]); 
    pts[2] = PVector.add(pts[3],vector); 

    for(int j = 0; j < frequency; j++){ 
     PMatrix3D f_rotate = new PMatrix3D(); 
     f_rotate.rotate(j*2*PI/frequency , 0,0,1); 

     Face f = new Face(); 
     for(PVector pt : pts){ 
     PVector p = new PVector(); 
     f_rotate.mult(pt,p); 
     f.add(p.get()); 
     } 
     faces.add(f); 
    } 

    pts[0] = pts[3]; 
    } 
} 
void draw(){ 
    background(255); 
    lights(); 

    translate(width * .5, height * .5,0); 
    rotateY(map(mouseX,0,width,-PI,PI)); 
    rotateX(map(mouseY,0,height,-PI,PI)); 
    drawAxes(100); 
    pushMatrix(); 
    translate(0,0,-frequency * length * .25); 
    for(Face f : faces){ 
    beginShape(mousePressed ? QUADS : POINTS); 
     for(PVector p : f.pts) vertex(p.x,p.y,p.z); 
    endShape(); 
    } 
    popMatrix(); 
} 
void keyPressed(){ 
    if(keyCode == UP && frequency < 32) frequency++; 
    if(keyCode == DOWN && frequency > 3) frequency--; 
    setupZome(); 
} 
void drawAxes(int size){ 
    stroke(192,0,0); 
    line(0,0,0,size,0,0); 
    stroke(0,192,0); 
    line(0,0,0,0,size,0); 
    stroke(0,0,192); 
    line(0,0,0,0,0,size); 
} 
class Face{ 
    ArrayList<PVector> pts = new ArrayList<PVector>(); 
    Face(){} 
    void add(PVector p){ 
    if(pts.size() <= 4) pts.add(p); 
    } 
} 

而且這裏有幾個截圖:

polar zonohedron quadspolar zonohedron pointspolar zonohedron quads angled