インタビュー
ずっと前に、私はグラフィックス プログラミングの職について多くの候補者と面接しました。 優れた面接官になるのは大変な仕事です。私の初期の試みは素晴らしいものではありませんでした。 時間が経つにつれて、会話を始めるためにこの質問を思いつきました。
私: 同僚が「円を描く必要がある」と言いに来たらどうしますか?
- 候補者0: 分かりません。
- 候補者 1: わかりません。 コンパス?
- 候補者 2: うーん。 小さな文字「o」を印刷します。
- 候補 3: 平方根を実行する必要があります。
- 候補 4: Sines と Cosines を使用する必要があります。
- 候補 5: Bresenham の円描画アルゴリズムがそれを行うはずです。
- 候補者 6: ライブラリ関数を探して、ドキュメントが存在する場所を示すように彼らに言います。 発明するよりも再利用する方が良いです。
- 候補者 7: 私なら、「わかりません。 なぜ円を描きたいのですか?」という質問は、実際には円を描く必要がないからかもしれません。 おそらく、平方根を使用して円の内側に何があるかを知る必要があるでしょう。 もしかしたら楕円が必要なのかもしれません。 描かれた円が本当に必要であると判断したら、その円はどこに描かれるのでしょうか? 塗りつぶされるのでしょうか、無地でしょうか、それともパターンでしょうか? おそらく、これを行う関数がすでに存在しており、すでに十分にデバッグされていると思われます。 おそらく自分で記述する必要はありませんが、その場合はサインとコサインを使用し、ステップ サイズを半径の関数にしてください。 どれくらいの速度が必要ですか? デバイスによってはブレゼンハムが適切な場合があります。 プリンターでは、小さな文字「o」がマーカーとして機能する可能性があり、十分です。
議論
候補者 0、1、2、3、4、5 はすべて森を逃しました。 あなたが面接官の場合は、質問の半分は質問の中で相手がどのような人なのかを理解できるように必ずサポートしてください。これは質問の半分だからです。 あなたが候補者の場合は、2 つの部分からなる質問に注意してください。
あなたが面接を受ける側である場合は、候補者 0 が行った場所で決して立ち止まらないでください。 候補 1 と 2 は、面接官が別の質問をするのに十分なフックとなります。 あなたが面接官の場合、候補者はストレスの多い状況にあり、詳細を明らかにするために少しの助けが必要であることを忘れないでください。
候補 3、4、および 5 はそれぞれ、技術的な解決策を提案していますが、どれもうまくいく可能性はありますが、どれも常に最善というわけではありません。 あなたが候補者である場合は、自分の答えについて話し続けてください。 あなたが面接官であれば、「それは(速い、安全、正しいなど)でしょうか?」と指導してください。
候補 6 と 7 は、実用的な尺度で異なる位置に当てはまります。 最適なものを決定するには、さらに多くの質問と議論が必要です。
答え
面接の質問は円を描くことについてはあまり重要ではありませんが、それがもしあなたがまだ読んでいる理由であるなら、ここに答え 2、3、4、5、6 の JSL があります。
小文字のo、3通り
New Window( "Candidate 2, literal",
Graph Box(
xaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
yaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
Text( Center Justified, {50, 50}, "o" ) // "o" sits above the point
)
);
Text sits above the baseline.テキストはベースラインの上に配置されます。
New Window( "Candidate 2, modified",
Graph Box(
xaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
yaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
markersize(10),
marker( markerstate("O"), {50, 50}) // capital "O" is somewhat centered
)
);
Using a marker with a capital O.大文字の O のマーカーを使用します。
New Window( "Candidate 2, reinvented",
Graph Box(
xaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
yaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
Marker Size( 100 ),
Marker( Marker State( 8 ), {50, 50} ) // bigger is thicker
)
);
If you can use a marker, then you can pick the circle symbol.マーカーを使用できる場合は、円記号を選択できます。
平方根、2 つの方法
New Window( "Candidate 3, sqrt hard way",
Graph Box(
framesize( 300, 300 ),
xaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
yaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
// draw a circle at 50,50 with radius 30 using sqrt
// a lot of code, and not too pretty on the left and right
step=3; // to make the problem more obvious, use 1 to almost hide it
For( x = 0, x < 30, x += step,
// hyp = sqrt(x^2 + y^2)
// hyp^2 = x^2 + y^2
// hyp^2 - x^2 = y^2
y1 = Sqrt( 30 ^ 2 - x ^ 2 );
y2 = Sqrt( 30 ^ 2 - (x + step) ^ 2 );
// do all four quadrants in parallel
Line( {50 + x, 50 + y1}, {50 + (x + step), 50 + y2} );
Line( {50 - x, 50 + y1}, {50 - (x + step), 50 + y2} );
Line( {50 - x, 50 - y1}, {50 - (x + step), 50 - y2} );
Line( {50 + x, 50 - y1}, {50 + (x + step), 50 - y2} );
)
)
);
The sqrt approach looks rough on the left and right because of the equal-sized steps in x.sqrt アプローチは、x のステップが同じサイズであるため、左右で粗く見えます。
New Window( "Candidate 3, sqrt with YFunction",
Graph Box(
framesize( 300, 300 ),
xaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
yaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
// draw a circle at 50,50 with radius 30 using sqrt
// sqrt has two answers. Looks nice, thanks YFunction. Only a small gap.
Y Function( 50 + Sqrt( 30 ^ 2 - (x - 50) ^ 2 ), x );// top
Y Function( 50 - Sqrt( 30 ^ 2 - (x - 50) ^ 2 ), x );// bottom
)
);
The Y Function adjusts the x step size automatically.Y 機能は、x ステップ サイズを自動的に調整します。
サインとコサイン
New Window( "Candidate 4, sin/cos with XYFunction",
Graph Box(
framesize( 300, 300 ),
xaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
yaxis( Add Ref Line( 50, "Solid", "Black", "", 1 ) ),
// draw a circle at 50,50 with radius 30 using sin/cos
XY Function( 50 + 30 * Cos( t ), 50 + 30 * Sin( t ), t, Min( 0 ), Max( 2 * Pi() ) )
)
);
I really like the XYFunction for this parametric description of a circle.私は円をパラメトリックに記述する XYFunction がとても気に入っています。
ブレゼンハム
//Bresenham.
// using pixel functions (There is no reason I can think of to
// use this code; everything else will be faster! A long time
// ago there was no floating point arithmetic or sin/cos/sqrt
// and tricks like this were useful.)
drawCircle = Function( {xc, yc, x, y}, // not really pixels. this is not a good match for JMP!
Marker( Marker State( 0 ), {xc + x, yc + y} ); // invented for primitive hardware without
Marker( Marker State( 0 ), {xc - x, yc + y} ); // floating point.
Marker( Marker State( 0 ), {xc + x, yc - y} );
Marker( Marker State( 0 ), {xc - x, yc - y} );
Marker( Marker State( 0 ), {xc + y, yc + x} );
Marker( Marker State( 0 ), {xc - y, yc + x} );
Marker( Marker State( 0 ), {xc + y, yc - x} );
Marker( Marker State( 0 ), {xc - y, yc - x} );
);
circleBres = Function( {xc, yc, r}, // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/
x = 0;
y = r;
d = 3 - 2 * r;
drawCircle( xc, yc, x, y );
While( y >= x,
x++;
If( d > 0,
y--;
d = d + 4 * (x - y) + 10;
,
d = d + 4 * x + 6
);
drawCircle( xc, yc, x, y );
);
);
New Window( "Candidate 5, really hard way using pixels",
Graph Box(
framesize( 900, 900 ),xscale(0,1000),yscale(0,1000),
xaxis( Add Ref Line( 500, "Solid", "Black", "", 1 ) ),
yaxis( Add Ref Line( 500, "Solid", "Black", "", 1 ) ),
// draw a circle at 500,500 with radius 300
circleBres( 500, 500, 300 ),
text({300,700},"Zoom in for detail")
)
);
The point of the Bresenham circle drawing algorithm is to only use integers and avoid multiply and divide ( *2 and *4 can be shift operations.)ブレゼンハム円描画アルゴリズムのポイントは、整数のみを使用し、乗算と除算を避けることです (*2 と *4 はシフト演算になる可能性があります)。
Zoomed in the pixels always step in either x or y or both.ピクセルをズームインすると、常に x または y のいずれか、または両方がステップインされます。
ライブラリ関数
New Window( "Candidate 6, Circle Function",
Graph Box(
xaxis( Show Major Grid( 1 ) ),
yaxis( Show Major Grid( 1 ) ),
Circle( {50, 50}, 30 )
)
);
The Circle Function uses the Y dimension and makes a visibly round circle. Because the axes are not isometric, something seems odd.Circle 関数は、Y 次元を使用して、目に見える丸い円を作成します。 軸が等長ではないので、何か奇妙に見えます。
New Window( "Candidate 6, Circle on square paper",
Graph Box( framesize(400,400),
xaxis( Show Major Grid( 1 ) ),
yaxis( Show Major Grid( 1 ) ),
Circle( {50, 50}, 30 )
)
);
The graph's popup menu, Size/Scale->SizeToIsometric will automatically make this adjustment.グラフのポップアップ メニューの [Size/Scale] ->[SizeToIsometric] を選択すると、この調整が自動的に行われます。
楕円関数の方がよいかもしれません。
New Window( "Candidate 6, Oval function",
Graph Box( // framesize(600,400),
x=50;
y=50;
r=30;
Oval( x-r, y-r, x+r, y+r );
)
);
The Oval function has a clear API for the vertical and horizontal dimensions.Oval 関数には、垂直方向と水平方向の寸法に関する明確な API があります。
油圧
I traced a DVD; the cyborg hand is really teaching about hydraulics and levers and putting pieces together.DVD をトレースしました。サイボーグハンドは実際に油圧とレバーについて教え、部品を組み立てています。
私は 1 月と 2 月をかけて、5 歳児がこのメガ サイボーグ ハンドを組み立てるのを手伝いました。 私は妥当な最低年齢として 7 歳をお勧めします (ボックスも同様です)。 1日おきくらいに10分から15分のセッションを行いました。 約30ドルという驚きの価格です。 一番良かったのは、先日家に歩いているときに、5歳の息子が掘削機を見つけて、油圧シリンダーについて教えてくれたことです。
Huge! Actually too big for a five year old.巨大な! 実際、5歳児には大きすぎます。