Entrevista
Hace mucho tiempo entrevisté a muchos candidatos para muchos puestos de programación gráfica. Ser un buen entrevistador es un trabajo duro; Mis primeros intentos no fueron muy buenos. Con el tiempo se me ocurrió esta pregunta para iniciar una conversación.
Yo: ¿Qué haces si un compañero de trabajo se te acerca y te dice "Necesito dibujar un círculo"?
- Candidato 0: No lo sé.
- Candidato 1: No lo sé. ¿Un compás?
- Candidato 2: Mmmmm. Imprimiría una letra minúscula "o".
- Candidato 3: La raíz cuadrada debería bastar.
- Candidato 4: Los senos y cosenos deberían hacerlo.
- Candidato 5: El algoritmo de dibujo de círculos de Bresenham debería ser suficiente.
- Candidato 6: Les diría que busquen una función de biblioteca y les mostraría dónde se encuentra la documentación. Es mejor reutilizar que inventar.
- Candidato 7: Yo diría "No lo sé". ¿Por qué quieres dibujar un círculo?" porque tal vez realmente no necesitan dibujar uno. Quizás necesiten saber qué hay dentro del círculo usando la raíz cuadrada. Quizás necesiten una elipse. Una vez que decidimos que es realmente necesario dibujar un círculo, ¿dónde lo dibujaremos? ¿Estará relleno, sólido o con un patrón? Lo más probable es que ya exista una función para hacer esto y ya esté bien depurada. Probablemente no necesites escribirlo tú mismo, pero si lo haces, usa senos y cosenos y haz que el tamaño del paso sea una función del radio. ¿Qué tan rápido debe ser? Dependiendo del dispositivo, Bresenham podría ser apropiado. En una impresora, una letra minúscula "o" podría funcionar como marcador y ser lo suficientemente buena.
Discusión
Todos los candidatos 0,1,2,3,4,5 se perdieron el bosque. Si usted es el entrevistador, asegúrese de ayudarlo a ver a la otra persona en la pregunta, porque esa es la mitad de la pregunta. Y si eres el candidato, cuidado con las preguntas de dos partes.
Si eres el entrevistado, nunca te detengas donde lo hizo el candidato 0. Los candidatos 1 y 2 proporcionan el gancho suficiente para que el entrevistador haga otra pregunta. Si usted es el entrevistador, recuerde que el candidato se encuentra en una situación estresante y necesita un poco de ayuda para desbloquear más detalles.
Los candidatos 3, 4 y 5 sugieren cada uno una solución técnica, cualquiera de las cuales podría funcionar, pero ninguna es siempre la mejor. Si eres el candidato, sigue hablando de tu respuesta. Si usted es el entrevistador, infórmele: "¿será (rápido, seguro, correcto, etc.)?"
Los candidatos 6 y 7 se ubican en diferentes lugares de la escala pragmática. Se necesitan más preguntas y debates para determinar la mejor opción.
Respuestas
La pregunta de la entrevista no trata mucho sobre dibujar un círculo, pero si es por eso que todavía estás leyendo, aquí tienes JSL para las respuestas 2,3,4,5,6.
Letra o minúscula, tres formas
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.Text sits above the baseline.Text sits above the baseline.Text sits above the baseline.Text sits above the baseline.El texto se sitúa por encima de la línea base.
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.Using a marker with a capital O.Using a marker with a capital O.Using a marker with a capital O.Using a marker with a capital O.Usando un marcador con una O mayúscula.
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.If you can use a marker, then you can pick the circle symbol.If you can use a marker, then you can pick the circle symbol.If you can use a marker, then you can pick the circle symbol.If you can use a marker, then you can pick the circle symbol.Si puedes usar un marcador, puedes elegir el símbolo del círculo.
Raíz cuadrada, dos formas
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.The sqrt approach looks rough on the left and right because of the equal-sized steps in x.The sqrt approach looks rough on the left and right because of the equal-sized steps in x.The sqrt approach looks rough on the left and right because of the equal-sized steps in x.The sqrt approach looks rough on the left and right because of the equal-sized steps in x.El enfoque sqrt parece tosco a izquierda y derecha debido a los pasos de igual tamaño en 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.The Y Function adjusts the x step size automatically.The Y Function adjusts the x step size automatically.The Y Function adjusts the x step size automatically.The Y Function adjusts the x step size automatically.La función Y ajusta automáticamente el tamaño del paso x.
Senos y cosenos
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.I really like the XYFunction for this parametric description of a circle.I really like the XYFunction for this parametric description of a circle.I really like the XYFunction for this parametric description of a circle.I really like the XYFunction for this parametric description of a circle.Me gusta mucho la función XY para esta descripción paramétrica de un círculo.
Bresenham
//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.)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.)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.)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.)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.)El objetivo del algoritmo de dibujo de círculos de Bresenham es utilizar únicamente números enteros y evitar multiplicar y dividir (*2 y *4 pueden ser operaciones de desplazamiento).
Zoomed in the pixels always step in either x or y or both.Zoomed in the pixels always step in either x or y or both.Zoomed in the pixels always step in either x or y or both.Zoomed in the pixels always step in either x or y or both.Zoomed in the pixels always step in either x or y or both.Los píxeles ampliados siempre avanzan en x, y o ambos.
Funciones de biblioteca
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.The Circle Function uses the Y dimension and makes a visibly round circle. Because the axes are not isometric, something seems odd.The Circle Function uses the Y dimension and makes a visibly round circle. Because the axes are not isometric, something seems odd.The Circle Function uses the Y dimension and makes a visibly round circle. Because the axes are not isometric, something seems odd.The Circle Function uses the Y dimension and makes a visibly round circle. Because the axes are not isometric, something seems odd.La función Círculo utiliza la dimensión Y y forma un círculo visiblemente redondo. Como los ejes no son isométricos, algo parece extraño.
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.The graph's popup menu, Size/Scale->SizeToIsometric will automatically make this adjustment.The graph's popup menu, Size/Scale->SizeToIsometric will automatically make this adjustment.The graph's popup menu, Size/Scale->SizeToIsometric will automatically make this adjustment.The graph's popup menu, Size/Scale->SizeToIsometric will automatically make this adjustment.El menú emergente del gráfico, Tamaño/Escala->TamañoAIsométrico realizará automáticamente este ajuste.
Quizás prefieras la función ovalada:
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.The Oval function has a clear API for the vertical and horizontal dimensions.The Oval function has a clear API for the vertical and horizontal dimensions.The Oval function has a clear API for the vertical and horizontal dimensions.The Oval function has a clear API for the vertical and horizontal dimensions.La función Oval tiene una API clara para las dimensiones verticales y horizontales.
Hidráulica
I traced a DVD; the cyborg hand is really teaching about hydraulics and levers and putting pieces together.I traced a DVD; the cyborg hand is really teaching about hydraulics and levers and putting pieces together.I traced a DVD; the cyborg hand is really teaching about hydraulics and levers and putting pieces together.I traced a DVD; the cyborg hand is really teaching about hydraulics and levers and putting pieces together.I traced a DVD; the cyborg hand is really teaching about hydraulics and levers and putting pieces together.Seguí un DVD; La mano cyborg realmente enseña sobre hidráulica, palancas y cómo ensamblar piezas.
Pasé enero y febrero ayudando a un niño de cinco años a armar esta Mega Mano Cyborg. Recomendaría siete años como edad mínima razonable (al igual que el cuadro); Hicimos sesiones de 10 a 15 minutos cada dos días aproximadamente. Es un valor increíble por alrededor de $30. Lo mejor: caminando a casa el otro día, el niño de 5 años ve una excavadora y me habla de los cilindros hidráulicos.
Huge! Actually too big for a five year old.Huge! Actually too big for a five year old.Huge! Actually too big for a five year old.Huge! Actually too big for a five year old.Huge! Actually too big for a five year old.¡Enorme! En realidad, demasiado grande para un niño de cinco años.