Probé el código del Sr. Warren, pero no produjo resultados confiables.
Por ejemplo,
ExpandToBound(new Size(640,480), new Size(66, 999)).Dump();
// {Width=66, Height=49}
ExpandToBound(new Size(640,480), new Size(999,50)).Dump();
// {Width=66, Height=50}
Se puede ver, altura = 49 y la altura = 50 en otro.
Aquí está el mío (versión del Sr.Código de Warren) sin la discrepancia y una ligera refactor:
// Passing null for either maxWidth or maxHeight maintains aspect ratio while
// the other non-null parameter is guaranteed to be constrained to
// its maximum value.
//
// Example: maxHeight = 50, maxWidth = null
// Constrain the height to a maximum value of 50, respecting the aspect
// ratio, to any width.
//
// Example: maxHeight = 100, maxWidth = 90
// Constrain the height to a maximum of 100 and width to a maximum of 90
// whichever comes first.
//
private static Size ScaleSize(Size from, int? maxWidth, int? maxHeight)
{
if (!maxWidth.HasValue && !maxHeight.HasValue) throw new ArgumentException("At least one scale factor (toWidth or toHeight) must not be null.");
if (from.Height == 0 || from.Width == 0) throw new ArgumentException("Cannot scale size from zero.");
double? widthScale = null;
double? heightScale = null;
if (maxWidth.HasValue)
{
widthScale = maxWidth.Value/(double)from.Width;
}
if (maxHeight.HasValue)
{
heightScale = maxHeight.Value/(double)from.Height;
}
double scale = Math.Min((double)(widthScale ?? heightScale),
(double)(heightScale ?? widthScale));
return new Size((int)Math.Floor(from.Width * scale), (int)Math.Ceiling(from.Height * scale));
}
Por favor, no abusar de los árbitros por el estilo. Es mucho mejor hacer un rectángulo struct_immutable_ que tenga un ancho y un campo de altura, y luego escribir un método ExpandToBound que tome dos rectángulos y devuelva el rectángulo resultante. Es mucho más fácil razonar acerca de las funciones cuando las implementa como _funciones_. Argumentos entran, salen los resultados; las funciones no cambian el estado que no poseen. –
@Eric Lippert - De acuerdo, el ejemplo no fue la función que realmente implementé, solo una versión reducida para evitar confundir el problema con las estructuras Rectangle u otras cosas que no forman parte del núcleo del problema. –