# NAME

PDL::Drawing::Prima::Utils - A handful of useful utilities.

# DESCRIPTION

These functions provide a number of utilities that do not depend on the Prima toolkit but which are useful for Prima/PDL interaction. The first set of functions assist in converting colors from one format to another. The second set of functions are important for the auto-scaling calculations in PDL::Graphics::Prima. Strictly speaking, they should probably be defined somewhere in that module, but they reside here at the moment.

# FUNCTIONS

## color_to_rgb

Converts a Prima color value to RGB representation

If the input piddle has dimension (m, n, ...), the output piddle has dimensions (3, m, n, ...). The first element represents the red value, the second the green value, and the third the blue value. The resulting piddle is suitable for use in `rgb_to_color`

or `rgb_to_hsv`

.

The code for this routine is based on `value2rgb`

from Prima::colorDialog.

If `color_to_rgb`

encounters a bad value in the input, the output piddle will be marked as bad and the associated rgb values will all be marked with the bad value.

## rgb_to_color

Converts an RGB color to a Prima color value

Red, green, and blue values must fall between 0 and 255. Any values outside those boundaries will be truncated to the nearest boundary before computing the color.

The RGB values must be in the first dimension. In other words, the size of the first dimension must be three, so if the input piddle has dimensions (3, m, n, ...), the output piddle will have dimension (m, n, ...). The resulting piddle is suitable for use when specifying colors to drawing primitives.

The code for this routine is based on `rgb2value`

from Prima::colorDialog.

If `rgb_to_color`

encounters a bad value in any of the red, green, or blue values of the input, the output piddle will be marked as bad and the associated color values will all be marked as bad.

## hsv_to_rgb

Converts an HSV color triple to an RGB color triple

HSV stands for hue-saturation-value and is nicely represented by a cirle in a color palette. In this representation, the numbers representing saturation and value must be between 0 and 1; anything less than zero or greater than 1 will be truncated to the closest limit. The hue must be a value between 0 and 360, and again it will be truncated to the corresponding limit if that is not the case. For more information about HSV, see http://en.wikipedia.org/wiki/HSL_and_HSV.

Note that Prima's `hsv2rgb`

function, upon which this was based, had a special notation for a hue of -1, which always corresponded to a saturation of 0. Since a saturation of 0 means 'use greyscale', this function does not make any special use of that notation.

The first dimension of the piddles holding the hsv and rgb values must be size 3, i.e. the dimensions must look like (3, m, n, ...). The resulting piddle is suitable for input into rgb_to_color as well as manual manipulation.

The code for this routine is based on `hsv2rgb`

from Prima::colorDialog.

If `hsv_to_rgb`

encounters a bad value in any of the hue, saturation, or value quantities, the output piddle will be marked as bad and the associated rgb color values will all be marked as bad.

## rgb_to_hsv

Converts an RGB color triple to an HSV color triple

HSV stands for hue-saturation-value and is nicely represented by a cirle in a color palette. In this representation, the numbers representing saturation and value will run between 0 and 1. The hue will be a value between 0 and 360. For more information about HSV, see http://en.wikipedia.org/wiki/HSL_and_HSV.

Note that Prima's `rgb2hsv`

function, upon which this was based, returned a special value if r == g == b. In that case, it returned a hue of -1 and a saturation of zero. In the rgb color is a greyscale and the value is based simply on that. This function does not make use of that special hue value; it simply returns a hue value of 0.

The first dimension of the piddles holding the hsv and rgb values must be size 3, i.e. the dimensions must look like (3, m, n, ...). The resulting piddle is suitable for manual manipulation and input into hsv_to_rgb.

The code for this routine is based on `rgb2hsv`

from Prima::colorDialog.

If `rgb_to_hsv`

encounters a bad value in any of the red, green, or blue values the output piddle will be marked as bad and the associated hsv values will all be marked as bad.

## minmaxforpair

Returns the min/max values for the pairs of coordinates x and y.

This function is only really useful in one very specific context: when the number of dimensions for x and y do not agree, and when you have bad data in x, y, or both.

Suppose that you know that x and y are good. Then you could get the min/max data using the `minmax`

function:

```
my ($xmin, $xmax) = $x->minmax;
my ($ymin, $ymax) = $y->minmax;
```

On the other hand, if you have data but you know that the dimensions of x and y match, you could modify the above like so:

```
my ($xmin, $xmax) = $x->where($x->isgood & $y->isgood)->minmax;
my ($ymin, $ymax) = $y->where($x->isgood & $y->isgood)->minmax;
```

However, what if you have only one-dimensional x-data but two-dimensional y-data? For example, you want to plot mutliple y datasets against the same x-coordinates. In that case, if some of the x-data is bad, you could probably hack something, but if some of the y-data is bad you you will have a hard time picking out the good pairs, and getting the min/max from them. That is the purpose of this function.

Output is set bad if no pair of x/y data is good.

## collate_min_max_wrt_many

```
Signature: ($min(N_pixels), $max(N_pixels))
= collate_min_max_wrt_many(
$min_to_collate(M); $min_index(M);
$max_to_collate(M); $max_index(M);
N_pixels; $p1(M); $p2(M); ...);
```

Collates the min/max two piddles according to their supplied indices.

This function pretty much only makes sense in the context of PDL::Graphics::Prima and it's auto-scaling calculations. Here's how it works.

Suppose you're drawing a collection of colored blobs. Your blobs have various radii and you want to know the min and the max x-positions, collated for each radius. In other words, for all the blobs with radius 1, give me the min and the max; for all the blobs with radius 2, give me the min and the max; etc. However, you are not going to draw the blobs that have a badvalue for a the y position or the color---badvalues for any of these mean "skip me". You only want to know the minima and maxima for the blobs that you intend to draw. Also, let's assume that the widget onto which you intend to draw is 500 pixels wide.

For that situation, you would call collate_min_max_wrt_many like so:

```
my ($min, $max) = PDL::collate_min_max_wrt_many($x, $xRadii, $x, $xRadii
, 500, $y, $yRadii, $colors);
```

The arguments are interpreted as follows. The first two piddles are the values and the indices of the data from which we wish to draw the minima. Here we want to find the smallest value of x, collated according to the specified pixel radii. The next two piddles are the values and indices of the data from which we wish to draw the maxima. The fifth argument, a scalar number, indicates the maximum collation bin.

The remainder of the arguments are values against which we want to check for bad values. For example, suppose the first (x, y) pair is (2, inf). This point will not be drawn, because infinity cannot be drawn, so I will not want to collate that x-value of 2, regardless of the xRadius with which it corresponds. So, each value of x is included in the min/max collation only if all the other piddles have good values at the same index.

This function threads over as many as 20 extra piddles, checking each of them to see if they have bad values, inf, or nan. The limit to 20 piddles is a hard but arbitrary limit. It could be increased if the need arose, but the function would need to be recompiled.

This function is explicitly meant to handle bad values. The output piddles will have bad values for any index that was not represented in the calculation. If any of the supplied piddles have bad values, the corresponding position will not be analyzed.

## trim_collated_min

Returns a mask to trim a collated list of minima so that the resulting (masked off) entries are in strictly decreasing order with increasing index.

working here - this needs documentation

## trim_collated_max

Returns a mask to trim a collated list so that the resulting (masked off) entries are in strictly decreasing extremeness with increasing index.

working here - this needs documentation