2012-02-22 18 views
3

最近私はゾーネドロンを探していて、美しいものを作ったのはRob Bellです。私は無料でPolar Zonohedron Sketchup Pluginと遊んで、Processingを使ってジオメトリで遊んでいることを考えました。これまでのところ、プラグイン/ Rubyスクリプトを開いて直接移植しようとしましたが、私はRubyを経験しておらず、Sketchup Ruby API referenceを使っています。処理中の極座標をレンダリングする際の問題

コードのジオメトリ一部が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バツ。 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