file: glyph.c
/* glyph.c - function for generating glyphs for XmdvTool */
/* Copyright 1994, Matthew O. Ward
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without fee
* is granted provided that the above copyright notice appears in all copies.
* It is provided "as is" without express or implied warranty.
*/
/* draw data using a star glyph pattern. Each dimension of a data point
controls the length of a ray emanating from a point, and the ends of all
N rays are connected with a polyline. Glyphs are currently spaced
evenly across the drawing area, using the square root of the data set
size to determine the number of rows and columns of glyphs. We could also
use 2 dimensions to control the location of the glyphs, but you tend to
get a lot of overlap. */
#include "XmdvTool.h"
#include "brush_oper.h"
#include "util.h"
#include "multi_select.h"
extern Widget appShell;
extern GC gc;
extern unsigned long color_cells[NUM_COLOR_CELLS];
extern XColor outline_col;
extern int dims, data_size;
extern double dim_min[MAXDIM], dim_max[MAXDIM];
extern int X_SIZE, Y_SIZE;
/* is this a color display? */
extern int COLOR;
char message[30];
Arg wargs[10];
void do_glyph(Widget w)
{
int i, j, endx, endy, blocksize, basex, basey, blockcnt;
XPoint poly[MAXDIM+1];
double data[MAXDIM], norm[MAXDIM];
unsigned long pixel; /* the brush color pixel value */
/* figure out how big each glyph will be by dividing up the drawing area */
blocksize = (double)(X_SIZE)/(1.0 + sqrt((double)data_size));
blockcnt = .5 + sqrt((double)data_size);
/* no text or brush coverage drawn, so just choose colors based on whether
brushed points will be displayed or not */
if(COLOR == 1)
for(i=0; i<data_size; i++)
{
basex = blocksize * (i%blockcnt) + blocksize/2;
basey = blocksize * (i/blockcnt) + blocksize/2;
get_data(data, i);
pixel = ColorFromOperations(data);
/* if this point is masked, skip it */
if(pixel == COLOR_NONE)
continue;
XSetForeground(XtDisplay(w),gc, pixel);
for(j=0; j<dims; j++)
norm[j] = (data[j] - dim_min[j]) * ((double)(blocksize/2.0)) /
(dim_max[j] - dim_min[j]);
for(j=0; j<dims; j++)
{
endx = (double)basex + norm[j] * cos(((double)(j))*2.0*
M_PI/((double)(dims)));
endy = (double)basey - norm[j] * sin(((double)(j))*2.0*
M_PI/((double)(dims)));
poly[j].x = endx;
poly[j].y = endy;
XDrawLine(XtDisplay(w), XtWindow(w), gc, basex, basey,
endx, endy);
}
poly[dims].x = poly[0].x;
poly[dims].y = poly[0].y;
XDrawLines(XtDisplay(w), XtWindow(w), gc, poly, dims+1,
CoordModeOrigin);
}
else
for(i=0; i<data_size; i++)
{
/* get location for ith glyph */
basex = blocksize * (i%blockcnt) + blocksize/2;
basey = blocksize * (i/blockcnt) + blocksize/2;
get_data(data, i);
/* compute normalized length of each ray for sample */
for(j = 0;j < dims;j++)
norm[j] = (data[j] - dim_min[j]) * ((double)(blocksize/2.0)) /
(dim_max[j] - dim_min[j]);
/* compute endpoints for each ray based on evenly spaced angles */
/* from center */
for(j = 0;j < dims;j++)
{
endx = (double)basex + norm[j] * cos(((double)(j))*2.0*
M_PI/((double)(dims)));
endy = (double)basey - norm[j] * sin(((double)(j))*2.0*
M_PI/((double)(dims)));
poly[j].x = endx;
poly[j].y = endy;
/* draw rays */
XDrawLine(XtDisplay(w), XtWindow(w), gc, basex, basey,
endx, endy);
}
/* draw bounding polyline */
poly[dims].x = poly[0].x;
poly[dims].y = poly[0].y;
XDrawLines(XtDisplay(w), XtWindow(w), gc, poly, dims+1,
CoordModeOrigin);
}
}
/*
* RedrawSingleGlyph() - Redraws a single glyph on the canvas. Usefull when
* doing multi-select for example.
*/
void RedrawSingleGlyph(Widget w, int glyphno)
{
int j, endx, endy, blocksize, basex, basey, blockcnt;
XPoint poly[MAXDIM+1];
double data[MAXDIM], norm[MAXDIM];
/* figure out how big each glyph will be by dividing up the drawing area */
blocksize = (double)(X_SIZE)/(1.0 + sqrt((double)data_size));
blockcnt = .5 + sqrt((double)data_size);
/* get location for glyph */
basex = blocksize * (glyphno%blockcnt) + blocksize/2;
basey = blocksize * (glyphno/blockcnt) + blocksize/2;
get_data(data, glyphno);
/* set the color */
if(COLOR == 1)
{
if(MultiSelectCovered(glyphno))
XSetForeground(XtDisplay(w),gc, color_cells[CCELL_PAINT]);
else if(covered(data) == 1)
XSetForeground(XtDisplay(w),gc, color_cells[CCELL_HIGHLIGHT]);
else
XSetForeground(XtDisplay(w),gc, color_cells[CCELL_DATA]);
}
else
XSetForeground(XtDisplay(w),gc, color_cells[CCELL_TEXT]);
/* draw */
for(j = 0;j < dims;j++)
norm[j] = (data[j] - dim_min[j]) * ((double)(blocksize/2.0)) /
(dim_max[j] - dim_min[j]);
for(j = 0;j < dims;j++)
{
endx = (double)basex + norm[j] * cos(((double)(j))*2.0*
M_PI/((double)(dims)));
endy = (double)basey - norm[j] * sin(((double)(j))*2.0*
M_PI/((double)(dims)));
poly[j].x = endx;
poly[j].y = endy;
XDrawLine(XtDisplay(w), XtWindow(w), gc, basex, basey, endx, endy);
}
poly[dims].x = poly[0].x;
poly[dims].y = poly[0].y;
XDrawLines(XtDisplay(w), XtWindow(w), gc, poly, dims+1, CoordModeOrigin);
}
/*
* GlyphDrawAverage() - Draw an average value on the glyph display.
*
* PARAMETERS
* data The average point to draw
*
* RETURNS
* void
*/
void GlyphDrawAverage(double data[MAXDIM])
{
Widget canvas_w; /* the canvas */
int j, endx, endy, blocksize, basex, basey, blockcnt;
XPoint poly[MAXDIM+1];
double norm[MAXDIM];
int glyphno = data_size; /* put the glyph after all data */
/* get the canvas widget */
if(!(canvas_w = WcFullNameToWidget(appShell,"*canvas")))
{
fprintf(stderr, "Error getting *canvas in GlyphDrawAverage()\n");
return;
}
/* figure out how big each glyph will be by dividing up the drawing area */
blocksize = (double)(X_SIZE)/(1.0 + sqrt((double)data_size));
blockcnt = .5 + sqrt((double)data_size);
/* get location for glyph */
basex = blocksize * (glyphno%blockcnt) + blocksize/2;
basey = blocksize * (glyphno/blockcnt) + blocksize/2;
/* compute normalized length of each ray for sample */
for(j = 0;j < dims;j++)
norm[j] = (data[j] - dim_min[j]) * ((double)(blocksize/2.0)) /
(dim_max[j] - dim_min[j]);
/* compute endpoints for each ray based on evenly spaced angles */
/* from center */
for(j = 0;j < dims;j++)
{
endx = (double)basex + norm[j] * cos(((double)(j))*2.0*
M_PI/((double)(dims)));
endy = (double)basey - norm[j] * sin(((double)(j))*2.0*
M_PI/((double)(dims)));
poly[j].x = endx;
poly[j].y = endy;
/* draw rays */
XDrawLine(XtDisplay(canvas_w), XtWindow(canvas_w), gc, basex, basey,
endx, endy);
}
/* draw bounding polyline */
poly[dims].x = poly[0].x;
poly[dims].y = poly[0].y;
XDrawLines(XtDisplay(canvas_w), XtWindow(canvas_w), gc,
poly, dims+1, CoordModeOrigin);
}
C++ to HTML Conversion by ctoohtml