2011-11-18 13 views
9

Supongamos que quiero una cadena, por ejemplo "123", para llenar un rectángulo dado, así:Hacer una cadena de texto llenar un rectángulo

Show[Plot[x, {x, 0, 1}], 
    Graphics[{EdgeForm[Thick], Yellow, Rectangle[{.1, .5}, {.4, .9}]}], 
    Graphics[Text[Style["123", Red, Bold, 67], {.1, .5}, {-1, -1}]]] 

a string in a rectangle

Pero entregar a punto el tamaño de la fuente allí (67) para que llene el rectángulo. ¿Cómo harías que una cadena arbitraria llene un rectángulo arbitrario?

Respuesta

8

Creo que este es un problema difícil conocido. La mejor respuesta que pude encontrar is from John Fultz.

TextRect[text_, {{left_, bottom_}, {right_, top_}}] := 
Inset[ 
    Pane[text, {Scaled[1], Scaled[1]}, 
    ImageSizeAction -> "ResizeToFit", Alignment -> Center], 
    {left, bottom}, {Left, Bottom}, {right - left, top - bottom}] 

Show[ 
Plot[x, {x, 0, 1}], 
Graphics[{ 
    {EdgeForm[Thick], Yellow, Rectangle[{.1, .5}, {.4, .9}]}, 
    TextRect[Style["123", Red, Bold], {{.1, .5}, {.4, .9}}] 
}] 
] 

enter image description here

+0

Nice approach. Por cierto, el texto se centrará verticalmente si usa 'Escalado [1]' en lugar de '{Escalado [1], Escalado [1]}'. – DavidC

+0

@David gracias. Intenté tu sugerencia, pero no funciona en mi sistema. : -/ –

+1

Añadiendo la opción Alinear panel -> Centro centrará el texto. –

2

Aquí hay un enfoque alternativo que convierte el texto en una textura que se asigna la de un polígono. Esto tiene la función de estirar el texto para adaptarse a la región

Show[Plot[x, {x, 0, 1}], 
    Graphics[{EdgeForm[Thick], Yellow, Rectangle[{.1, .5}, {.4, .9}]}], 
    Graphics[{Texture[ImageData[ 
     Rasterize[Style["123", Red, Bold], "Image", RasterSize -> 300, 
     Background -> None]]], 
     Polygon[{{0.1, 0.5}, {0.4, 0.5}, {0.4, 0.9}, {0.1, 0.9}}, 
     VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}]] 

Mathematica graphics

En función de una comparación más fácil (ya que en realidad no es de texto más.):

(* Render string/style s to fill a rectangle with left/bottom corner {l,b} and 
    right/top corner {r,t}. *) 
textrect[s_, {{l_,b_},{r_,t_}}] := Graphics[{ 
    Texture[ImageData[Rasterize[s, "Image", RasterSize->300, Background->None]]], 
    Polygon[{{l,b}, {r,b}, {r,t}, {l,t}}, 
      VertexTextureCoordinates->{{0,0},{1,0},{1,1},{0,1}}]}] 
+0

Ooh, me gusta la idea de estirarlo para llenar completamente el rectángulo. Pero se ve granulado cuando pruebo esto. Intenté jugar con el parámetro RasterSize en vano. Seguiré intentando. Gracias Brett! – dreeves

+0

No entiendo muy bien por qué no funciona si omites 'ImageData'. Además, parece que '" Imagen "' se puede cambiar a '" Datos "' (y luego omite 'ImageData'). – Szabolcs

+0

@Szabolcs No había considerado usar '" Datos "'. Por alguna razón, el 'Background -> None' no funciona correctamente de lo contrario cuando se incluye en una textura. (Tuve que preguntarle a otro desarrollador la primera vez que creé algo así usando 'Textura'.) –

1

La solución sugerida no funcionó cuando el argumento no estaba allí, utilicé la opción PlotRange para resolverlo. Lo envolví en una función; Opacidad, color del texto, etc. debe convertirse en opciones;

textBox[text_, color_, position_: {0, 0}, width_: 2, height_: 1] := 
    Graphics[{ 
    { 
    color, Opacity[.1], 
    Rectangle[position, position + {width, height}, 
     RoundingRadius -> 0.1] 
    } 
    , 
    Inset[ 
    Pane[text, {Scaled[1], Scaled[1]}, 
     ImageSizeAction -> "ResizeToFit", Alignment -> Center], 
    position, {Left, Bottom}, {width, height}] 
    }, PlotRange -> 
    Transpose[{position, position + {width, height}}]]; 
Cuestiones relacionadas