ユタ州のティーポットを描く


20

ユタティーポットもともとマーティン・ニューウェルが作成したが、3Dグラフィックスのプログラムをテストするための便利なオブジェクトです。

タスクは、透視投影でティーポットのワイヤーフレーム画像を作成することです。ソースコードアプリケーションのアイデアを促進するために、表示とカメラ制御を分離し、カウントから除外することができます。これにより、パラメーターと入力ファイルを変更し、コードを再利用してさまざまな画像を生成できますが、複雑なコマンドライン引数などを受け入れる本格的なユーティリティを作成する必要はありません。「ハッカー的」なバランスが求められています。

ワイヤーフレームティーポット

ref。StackOverflow:ユタ州のティーポットでベジェパッチはどのように機能しますか?

そのため、ここには3つのサブタスクがあります。

  • 元の形式ティーポットデータを読み込みます
  • deCasteljau分割またはその他の方法を使用して、パッチデータを再分割します。他の方法は、ベジエ基底行列を使用して、多項式(フォーリーやファンダム、ニューマンやスプロールなどの標準参照)、またはバーンスタイン基底法(まだ私を超えています)を評価しています。
  • ポイントが2Dに投影され(言語がネイティブで3Dをサポートしていない場合)、ビューがLookAtポイントを中心とし、垂直軸がティーポットの垂直軸と一致するアイポイントから見た各小さなパッチの輪郭を描きます。 (つまり、見晴らしの良い場所から「直立」して描く)。

ファイルから行指向のテキストデータを読み込むことは少し問題があると仮定すると、この挑戦は本当に得ることについてであるハンズオンバイキュービックベジェパッチデータを持ちます。

背面カリングの単純な通常のテストでは不十分であるため(パッチがすべて外側に向いているわけではありません)、隠線や表面の除去は必要ありません。ワイヤーフレームとして、背中が見える状態でうまく見えるはずです。見た目は、目からの距離に応じて線幅を調整することで改善できますが、これは厳密には必要ありません(自分のプログラムではこれを行いません)。

これは両方。ゴルフで競合する回答には、通常どおりカウントを含める必要があります。ただし、特別な言語ではない場合でも、通常とは異なる言語での提出を強くお勧めします。

コルモゴロフの複雑さの愛好家には、パッチの回転とミラーリングを追加することで完全なセットを再構築できる、より簡潔なデータセットがあります。また、Jim BlinnのA Trip Down the Graphics Pipelineには、個々のパッチに回転または他の対称性があるという事実を使用した、より簡潔な生成方法があります。体全体(または蓋)は、y軸を中心に回転する単一のベジェ曲線で説明できます。注ぎ口とハンドルは、それらのプロファイルの2つの曲線で記述し、次に、中間の制御点を選択して円形の押し出しを近似できます。


カウントにポイントの配列のカウントを含める必要がありますか?
TheDoctor 14年

私はむしろそれがファイルから来るのを見たいです...しかし、いや、それが来てもパッチデータを数える必要はありません。
luserはドローグ

glutSolidTeapotandのglutWireTeapotようなビルトインを許可しないことをお勧めます!
アンデルスカセオルグ16

@AndersKaseorg元のデータの読み込みを要求することでそれをカバーしたと思います。...そうは言っても、私この規則を強制するのに手間取っています。より厳密に有効な答えは、たとえそれが長くても簡単にチェックマークを取ります。
luserはドローグ

@luserdroog元のデータを読み取り、それを無視してを呼び出すソリューションを想像してくださいglutWireTeapot
アンデルスカセオルグ

回答:


9

処理(java)、314(237はカメラ制御なし)

配列定義を含まない:

void setup(){size(640,480,P3D);}void draw(){background(0);noFill();stroke(255);translate(width/2,height/2,70);scale(30);rotateX(map(mouseX,0,width,0,TWO_PI));rotateY(map(mouseY,0,height,0,TWO_PI));for(int[] p:patches){beginShape();for(int pt:p){vertex(data[pt-1][0],data[pt-1][1],data[pt-1][2]);}endShape(CLOSE);}}

データ配列定義:

float [][] data = {{1.4,0.0,2.4},
{1.4,-0.784,2.4},
{0.784,-1.4,2.4},
{0.0,-1.4,2.4},
{1.3375,0.0,2.53125},
{1.3375,-0.749,2.53125},
{0.749,-1.3375,2.53125},
{0.0,-1.3375,2.53125},
{1.4375,0.0,2.53125},
{1.4375,-0.805,2.53125},
{0.805,-1.4375,2.53125},
{0.0,-1.4375,2.53125},
{1.5,0.0,2.4},
{1.5,-0.84,2.4},
{0.84,-1.5,2.4},
{0.0,-1.5,2.4},
{-0.784,-1.4,2.4},
{-1.4,-0.784,2.4},
{-1.4,0.0,2.4},
{-0.749,-1.3375,2.53125},
{-1.3375,-0.749,2.53125},
{-1.3375,0.0,2.53125},
{-0.805,-1.4375,2.53125},
{-1.4375,-0.805,2.53125},
{-1.4375,0.0,2.53125},
{-0.84,-1.5,2.4},
{-1.5,-0.84,2.4},
{-1.5,0.0,2.4},
{-1.4,0.784,2.4},
{-0.784,1.4,2.4},
{0.0,1.4,2.4},
{-1.3375,0.749,2.53125},
{-0.749,1.3375,2.53125},
{0.0,1.3375,2.53125},
{-1.4375,0.805,2.53125},
{-0.805,1.4375,2.53125},
{0.0,1.4375,2.53125},
{-1.5,0.84,2.4},
{-0.84,1.5,2.4},
{0.0,1.5,2.4},
{0.784,1.4,2.4},
{1.4,0.784,2.4},
{0.749,1.3375,2.53125},
{1.3375,0.749,2.53125},
{0.805,1.4375,2.53125},
{1.4375,0.805,2.53125},
{0.84,1.5,2.4},
{1.5,0.84,2.4},
{1.75,0.0,1.875},
{1.75,-0.98,1.875},
{0.98,-1.75,1.875},
{0.0,-1.75,1.875},
{2.0,0.0,1.35},
{2.0,-1.12,1.35},
{1.12,-2.0,1.35},
{0.0,-2.0,1.35},
{2.0,0.0,0.9},
{2.0,-1.12,0.9},
{1.12,-2.0,0.9},
{0.0,-2.0,0.9},
{-0.98,-1.75,1.875},
{-1.75,-0.98,1.875},
{-1.75,0.0,1.875},
{-1.12,-2.0,1.35},
{-2.0,-1.12,1.35},
{-2.0,0.0,1.35},
{-1.12,-2.0,0.9},
{-2.0,-1.12,0.9},
{-2.0,0.0,0.9},
{-1.75,0.98,1.875},
{-0.98,1.75,1.875},
{0.0,1.75,1.875},
{-2.0,1.12,1.35},
{-1.12,2.0,1.35},
{0.0,2.0,1.35},
{-2.0,1.12,0.9},
{-1.12,2.0,0.9},
{0.0,2.0,0.9},
{0.98,1.75,1.875},
{1.75,0.98,1.875},
{1.12,2.0,1.35},
{2.0,1.12,1.35},
{1.12,2.0,0.9},
{2.0,1.12,0.9},
{2.0,0.0,0.45},
{2.0,-1.12,0.45},
{1.12,-2.0,0.45},
{0.0,-2.0,0.45},
{1.5,0.0,0.225},
{1.5,-0.84,0.225},
{0.84,-1.5,0.225},
{0.0,-1.5,0.225},
{1.5,0.0,0.15},
{1.5,-0.84,0.15},
{0.84,-1.5,0.15},
{0.0,-1.5,0.15},
{-1.12,-2.0,0.45},
{-2.0,-1.12,0.45},
{-2.0,0.0,0.45},
{-0.84,-1.5,0.225},
{-1.5,-0.84,0.225},
{-1.5,0.0,0.225},
{-0.84,-1.5,0.15},
{-1.5,-0.84,0.15},
{-1.5,0.0,0.15},
{-2.0,1.12,0.45},
{-1.12,2.0,0.45},
{0.0,2.0,0.45},
{-1.5,0.84,0.225},
{-0.84,1.5,0.225},
{0.0,1.5,0.225},
{-1.5,0.84,0.15},
{-0.84,1.5,0.15},
{0.0,1.5,0.15},
{1.12,2.0,0.45},
{2.0,1.12,0.45},
{0.84,1.5,0.225},
{1.5,0.84,0.225},
{0.84,1.5,0.15},
{1.5,0.84,0.15},
{-1.6,0.0,2.025},
{-1.6,-0.3,2.025},
{-1.5,-0.3,2.25},
{-1.5,0.0,2.25},
{-2.3,0.0,2.025},
{-2.3,-0.3,2.025},
{-2.5,-0.3,2.25},
{-2.5,0.0,2.25},
{-2.7,0.0,2.025},
{-2.7,-0.3,2.025},
{-3.0,-0.3,2.25},
{-3.0,0.0,2.25},
{-2.7,0.0,1.8},
{-2.7,-0.3,1.8},
{-3.0,-0.3,1.8},
{-3.0,0.0,1.8},
{-1.5,0.3,2.25},
{-1.6,0.3,2.025},
{-2.5,0.3,2.25},
{-2.3,0.3,2.025},
{-3.0,0.3,2.25},
{-2.7,0.3,2.025},
{-3.0,0.3,1.8},
{-2.7,0.3,1.8},
{-2.7,0.0,1.575},
{-2.7,-0.3,1.575},
{-3.0,-0.3,1.35},
{-3.0,0.0,1.35},
{-2.5,0.0,1.125},
{-2.5,-0.3,1.125},
{-2.65,-0.3,0.9375},
{-2.65,0.0,0.9375},
{-2.0,-0.3,0.9},
{-1.9,-0.3,0.6},
{-1.9,0.0,0.6},
{-3.0,0.3,1.35},
{-2.7,0.3,1.575},
{-2.65,0.3,0.9375},
{-2.5,0.3,1.125},
{-1.9,0.3,0.6},
{-2.0,0.3,0.9},
{1.7,0.0,1.425},
{1.7,-0.66,1.425},
{1.7,-0.66,0.6},
{1.7,0.0,0.6},
{2.6,0.0,1.425},
{2.6,-0.66,1.425},
{3.1,-0.66,0.825},
{3.1,0.0,0.825},
{2.3,0.0,2.1},
{2.3,-0.25,2.1},
{2.4,-0.25,2.025},
{2.4,0.0,2.025},
{2.7,0.0,2.4},
{2.7,-0.25,2.4},
{3.3,-0.25,2.4},
{3.3,0.0,2.4},
{1.7,0.66,0.6},
{1.7,0.66,1.425},
{3.1,0.66,0.825},
{2.6,0.66,1.425},
{2.4,0.25,2.025},
{2.3,0.25,2.1},
{3.3,0.25,2.4},
{2.7,0.25,2.4},
{2.8,0.0,2.475},
{2.8,-0.25,2.475},
{3.525,-0.25,2.49375},
{3.525,0.0,2.49375},
{2.9,0.0,2.475},
{2.9,-0.15,2.475},
{3.45,-0.15,2.5125},
{3.45,0.0,2.5125},
{2.8,0.0,2.4},
{2.8,-0.15,2.4},
{3.2,-0.15,2.4},
{3.2,0.0,2.4},
{3.525,0.25,2.49375},
{2.8,0.25,2.475},
{3.45,0.15,2.5125},
{2.9,0.15,2.475},
{3.2,0.15,2.4},
{2.8,0.15,2.4},
{0.0,0.0,3.15},
{0.0,-0.002,3.15},
{0.002,0.0,3.15},
{0.8,0.0,3.15},
{0.8,-0.45,3.15},
{0.45,-0.8,3.15},
{0.0,-0.8,3.15},
{0.0,0.0,2.85},
{0.2,0.0,2.7},
{0.2,-0.112,2.7},
{0.112,-0.2,2.7},
{0.0,-0.2,2.7},
{-0.002,0.0,3.15},
{-0.45,-0.8,3.15},
{-0.8,-0.45,3.15},
{-0.8,0.0,3.15},
{-0.112,-0.2,2.7},
{-0.2,-0.112,2.7},
{-0.2,0.0,2.7},
{0.0,0.002,3.15},
{-0.8,0.45,3.15},
{-0.45,0.8,3.15},
{0.0,0.8,3.15},
{-0.2,0.112,2.7},
{-0.112,0.2,2.7},
{0.0,0.2,2.7},
{0.45,0.8,3.15},
{0.8,0.45,3.15},
{0.112,0.2,2.7},
{0.2,0.112,2.7},
{0.4,0.0,2.55},
{0.4,-0.224,2.55},
{0.224,-0.4,2.55},
{0.0,-0.4,2.55},
{1.3,0.0,2.55},
{1.3,-0.728,2.55},
{0.728,-1.3,2.55},
{0.0,-1.3,2.55},
{1.3,0.0,2.4},
{1.3,-0.728,2.4},
{0.728,-1.3,2.4},
{0.0,-1.3,2.4},
{-0.224,-0.4,2.55},
{-0.4,-0.224,2.55},
{-0.4,0.0,2.55},
{-0.728,-1.3,2.55},
{-1.3,-0.728,2.55},
{-1.3,0.0,2.55},
{-0.728,-1.3,2.4},
{-1.3,-0.728,2.4},
{-1.3,0.0,2.4},
{-0.4,0.224,2.55},
{-0.224,0.4,2.55},
{0.0,0.4,2.55},
{-1.3,0.728,2.55},
{-0.728,1.3,2.55},
{0.0,1.3,2.55},
{-1.3,0.728,2.4},
{-0.728,1.3,2.4},
{0.0,1.3,2.4},
{0.224,0.4,2.55},
{0.4,0.224,2.55},
{0.728,1.3,2.55},
{1.3,0.728,2.55},
{0.728,1.3,2.4},
{1.3,0.728,2.4},
{0.0,0.0,0.0},
{1.5,0.0,0.15},
{1.5,0.84,0.15},
{0.84,1.5,0.15},
{0.0,1.5,0.15},
{1.5,0.0,0.075},
{1.5,0.84,0.075},
{0.84,1.5,0.075},
{0.0,1.5,0.075},
{1.425,0.0,0.0},
{1.425,0.798,0.0},
{0.798,1.425,0.0},
{0.0,1.425,0.0},
{-0.84,1.5,0.15},
{-1.5,0.84,0.15},
{-1.5,0.0,0.15},
{-0.84,1.5,0.075},
{-1.5,0.84,0.075},
{-1.5,0.0,0.075},
{-0.798,1.425,0.0},
{-1.425,0.798,0.0},
{-1.425,0.0,0.0},
{-1.5,-0.84,0.15},
{-0.84,-1.5,0.15},
{0.0,-1.5,0.15},
{-1.5,-0.84,0.075},
{-0.84,-1.5,0.075},
{0.0,-1.5,0.075},
{-1.425,-0.798,0.0},
{-0.798,-1.425,0.0},
{0.0,-1.425,0.0},
{0.84,-1.5,0.15},
{1.5,-0.84,0.15},
{0.84,-1.5,0.075},
{1.5,-0.84,0.075},
{0.798,-1.425,0.0},
{1.425,-0.798,0.0}
};

int [][] patches = {
    {32},
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},
{4,17,18,19,8,20,21,22,12,23,24,25,16,26,27,28},
{19,29,30,31,22,32,33,34,25,35,36,37,28,38,39,40},
{31,41,42,1,34,43,44,5,37,45,46,9,40,47,48,13},
{13,14,15,16,49,50,51,52,53,54,55,56,57,58,59,60},
{16,26,27,28,52,61,62,63,56,64,65,66,60,67,68,69},
{28,38,39,40,63,70,71,72,66,73,74,75,69,76,77,78},
{40,47,48,13,72,79,80,49,75,81,82,53,78,83,84,57},
{57,58,59,60,85,86,87,88,89,90,91,92,93,94,95,96},
{60,67,68,69,88,97,98,99,92,100,101,102,96,103,104,105},
{69,76,77,78,99,106,107,108,102,109,110,111,105,112,113,114},
{78,83,84,57,108,115,116,85,111,117,118,89,114,119,120,93},
{121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136},
{124,137,138,121,128,139,140,125,132,141,142,129,136,143,144,133},
{133,134,135,136,145,146,147,148,149,150,151,152,69,153,154,155},
{136,143,144,133,148,156,157,145,152,158,159,149,155,160,161,69},
{162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177},
{165,178,179,162,169,180,181,166,173,182,183,170,177,184,185,174},
{174,175,176,177,186,187,188,189,190,191,192,193,194,195,196,197},
{177,184,185,174,189,198,199,186,193,200,201,190,197,202,203,194},
{204,204,204,204,207,208,209,210,211,211,211,211,212,213,214,215},
{204,204,204,204,210,217,218,219,211,211,211,211,215,220,221,222},
{204,204,204,204,219,224,225,226,211,211,211,211,222,227,228,229},
{204,204,204,204,226,230,231,207,211,211,211,211,229,232,233,212},
{212,213,214,215,234,235,236,237,238,239,240,241,242,243,244,245},
{215,220,221,222,237,246,247,248,241,249,250,251,245,252,253,254},
{222,227,228,229,248,255,256,257,251,258,259,260,254,261,262,263},
{229,232,233,212,257,264,265,234,260,266,267,238,263,268,269,242},
{270,270,270,270,279,280,281,282,275,276,277,278,271,272,273,274},
{270,270,270,270,282,289,290,291,278,286,287,288,274,283,284,285},
{270,270,270,270,291,298,299,300,288,295,296,297,285,292,293,294},
{270,270,270,270,300,305,306,279,297,303,304,275,294,301,302,271},
{306}
};

より読みやすいバージョン:

void setup() {
  size(640,480,P3D);
}

void draw() {
  background(0);
  noFill();
  stroke(255);
  translate(width/2,height/2,70);
  scale(30);
  rotateX(map(mouseX,0,width,0,TWO_PI));
  rotateY(map(mouseY,0,height,0,TWO_PI));
  for (int[] p:patches) {
    beginShape();
    for (int pt:p) {
      vertex(data[pt-1][0],data[pt-1][2],data[pt-1][2]);
    }
    endShape(CLOSE); 
  }
}

そして、いくつかの写真:

完成品

いくつかの興味深い効果を持つ別のバージョン:

void setup(){size(640,480,P3D);}
void draw(){
  background(0);noFill();stroke(255);
  translate(width/2,height/2,70);scale(30);
  rotateX(map(mouseX,0,width,0,TWO_PI));rotateY(map(mouseY,0,height,0,TWO_PI));
  for(int[] p:patches){
    //beginShape(QUADS);
    for(int pt:p){
      for(int pu:p){
        //vertex(data[pu-1][0],data[pu-1][4],data[pu-1][2]);
        line(data[pt-1][0],data[pt-1][5],data[pt-1][2],data[pu-1][0],data[pu-1][6],data[pu-1][2]);
    }}
    //endShape(CLOSE);
  }
}

バージョン2


注ぎ口が形になるには、少なくとも一度パッチを分割する必要があります。
luserはドローグ

はい、2番目の写真の方が良いです。ただし、実際には細分化を行っていないようです。各パッチのエッジはベジェ曲線です...それでもそうですが、+ 1ティーポットのように見えます!
luserはドローグ

stroke(-1)より1バイト短いですstroke(255)
KritixiのLithos

11

追記

完全にゴルフではありませんが、これはdeCasteljauサブディビジョンとは異なるアプローチを示しています:基底多項式の評価。mat.psを使用します

(mat.ps)run[    % load matrix library, begin dictionary construction

/N 17
/C [ 0 7 4 ]   % Cam
/E [ 0 0 40 ] % Eye
/R 0 roty 120 rotx 90 rotz   % Rot: pan tilt twist
          matmul   matmul

/f(teapot)(r)file
/t{token pop exch pop}      % parse a number or other ps token
/s{(,){search not{t exit}if t 3 1 roll}loop}  % parse a comma-separated list
/r{token pop{[f 99 string readline pop s]}repeat}>>begin   % parse a count-prefixed paragraph of csv numbers
[/P[f r]/V[f r]/v{1 sub V exch get}        % Patches and Vertices and vert lookup shortcut
/B[[-1 3 -3 1][3 -6 3 0][-3 3 0 0][1 0 0 0]]              % Bezier basis matrix
/A{dup dup mul exch 2 copy mul 3 1 roll 1 4 array astore} % x->[x^3 x^2 x 1]
/M{[1 index 0 4 getinterval 2 index 4 4 getinterval       % flattened matrix->rowXcolumn matrix
3 index 8 4 getinterval 4 index 12 4 getinterval]exch pop}
/J{ C{sub}vop R matmul 0 get                              % perspective proJection  [x y z]->[X Y]
    aload pop E aload pop
    4 3 roll div exch neg
    4 3 roll add 1 index mul 4 1 roll
    3 1 roll sub mul}
>>begin

300 400 translate
1 14 dup dup scale div currentlinewidth mul setlinewidth  % global scale
/newline { /line {moveto /line {lineto} store} store } def
newline
P{
    8 dict begin
        [exch{v J 2 array astore}forall]/p exch def   % load patch vertices and project to 2D
        /X[p{0 get}forall] M B exch matmul B matmul def  % multiply control points by Bezier basis
        /Y[p{1 get}forall] M B exch matmul B matmul def

        0 1 N div 1 1 index .2 mul add{A/U exch def   % interpolate the polynomial over (u,v)/(N)
            /UX U X matmul def
            /UY U Y matmul def
            0 1 N div 1 1 index .2 mul add{A/V exch 1 array astore transpose def
                /UXV UX V matmul def
                /UYV UY V matmul def
                UXV 0 get 0 get
                UYV 0 get 0 get line
            }for
            newline
        }for

        0 1 N div 1 1 index .2 mul add{A/V exch def   % interpolate the polynomial over (u,v)/(N)
            /V [V] transpose def
            /XV X V matmul def
            /YV Y V matmul def
            0 1 N div 1 1 index .2 mul add{A/U exch 1 array astore transpose def
                /UXV U XV matmul def
                /UYV U YV matmul def
                UXV 0 get 0 get
                UYV 0 get 0 get line
            }for
            newline
        }for

    end

    %exit
}forall
stroke

ベジェベースのティーポット

1112

垂直線を取り除き、パラメーターを割引くと、この1112文字バージョンが生成されます。mat.psを使用します

(mat.ps)run[    % 12

/N 17
/C [ 0 7 4 ]   % Cam 
/E [ 0 0 40 ] % Eye 
/R 0 roty 120 rotx 90 rotz   % Rot: pan tilt twist
          matmul   matmul

/f(teapot)(r)file/t{token pop exch pop}/s{(,){search not{t exit}if t   % 1100
3 1 roll}loop}/r{token pop{[f 99 string readline pop 
s]}repeat}>>begin[/P[f r]/V[f r]/v{1 sub 
V exch get}/B[[-1 3 -3 1][3 -6 3 0][-3 3 0 0][1 0 0 0]]/A{dup dup mul exch
2 copy mul 3 1 roll 1 4 array astore}/M{[1 index 0 4 getinterval 2 index 4 4 getinterval    
3 index 8 4 getinterval 4 index 12 4 getinterval]exch pop}/J{C{sub}vop R matmul 0 get    
aload pop E aload pop 4 3 roll div exch neg 4 3 roll add 1 index mul 4 1 roll
3 1 roll sub mul}>>begin 300 400 translate
1 14 dup dup scale div currentlinewidth mul setlinewidth  
/newline{/line{moveto/line{lineto}store}store}def newline
P{8 dict begin[exch{v J 2 array astore}forall]/p
exch def/X[p{0 get}forall] M B exch matmul B matmul
def/Y[p{1 get}forall] M B exch matmul B matmul def 
0 1 N div 1 1 index .2 mul add{A/U exch def/UX U X matmul def/UY U Y matmul def 
0 1 N div 1 1 index .2 mul add{A/V exch 1 array astore transpose
def/UXV UX V matmul def/UYV UY V matmul def UXV 0 get 0 get UYV 0 get 0 get line}for
newline}for end}forall stroke

ベジェ基底ループ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.