static void do_ok (RunnerMFC me) { ExperimentMFC experiment = (ExperimentMFC) my data; Melder_assert (experiment -> trial >= 1 && experiment -> trial <= experiment -> numberOfTrials); my numberOfReplays = 0; if (experiment -> trial == experiment -> numberOfTrials) { experiment -> trial ++; my broadcastDataChanged (); Graphics_updateWs (my graphics); } else if (experiment -> breakAfterEvery != 0 && experiment -> trial % experiment -> breakAfterEvery == 0) { experiment -> pausing = TRUE; my broadcastDataChanged (); Graphics_updateWs (my graphics); } else { experiment -> trial ++; my broadcastDataChanged (); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } } }
static void do_oops (RunnerMFC me) { ExperimentMFC experiment = (ExperimentMFC) my data; Melder_assert (experiment -> trial >= 2 && experiment -> trial <= experiment -> numberOfTrials + 1); if (experiment -> trial <= experiment -> numberOfTrials) { experiment -> responses [experiment -> trial] = 0; experiment -> goodnesses [experiment -> trial] = 0; } experiment -> trial --; experiment -> responses [experiment -> trial] = 0; experiment -> goodnesses [experiment -> trial] = 0; experiment -> pausing = FALSE; my numberOfReplays = 0; my broadcastDataChanged (); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } }
void Art_Speaker_fillInnerContour (Art art, Speaker speaker, Graphics g) { double f = speaker -> relativeSize * 1e-3; double intX [1 + 16], intY [1 + 16], extX [1 + 11], extY [1 + 11]; double x [1 + 16], y [1 + 16]; double bodyX, bodyY; int i; Graphics_Viewport previous; Art_Speaker_toVocalTract (art, speaker, intX, intY, extX, extY, & bodyX, & bodyY); previous = Graphics_insetViewport (g, 0.1, 0.9, 0.1, 0.9); Graphics_setWindow (g, -0.05, 0.05, -0.05, 0.05); for (i = 1; i <= 16; i ++) { x [i] = intX [i]; y [i] = intY [i]; } Graphics_setGrey (g, 0.8); Graphics_fillArea (g, 16, & x [1], & y [1]); Graphics_fillCircle (g, bodyX, bodyY, 20 * f); Graphics_setGrey (g, 0.0); Graphics_resetViewport (g, previous); }
static void do_replay (RunnerMFC me) { ExperimentMFC experiment = (ExperimentMFC) my data; Melder_assert (experiment -> trial >= 1 && experiment -> trial <= experiment -> numberOfTrials); my numberOfReplays ++; Editor_broadcastDataChanged (me); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } }
void Matrix_drawAsSquares (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { Graphics_Colour colour = Graphics_inqColour (g); long ixmin, ixmax, iymin, iymax; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long nx = Matrix_getWindowSamplesX (me, xmin, xmax, &ixmin, &ixmax); if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ny = Matrix_getWindowSamplesY (me, ymin, ymax, &iymin, &iymax); double min, max = nx > ny ? nx : ny; double dx = (xmax - xmin) / max, dy = (ymax - ymin) / max; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & min, & max); double wAbsMax = fabs (max) > fabs (min) ? fabs (max) : fabs (min); for (long i = iymin; i <= iymax; i++) { double y = Matrix_rowToY (me, i); for (long j = ixmin; j <= ixmax; j++) { double x = Matrix_columnToX (me, j); double d = 0.95 * sqrt (fabs (my z[i][j]) / wAbsMax); if (d > 0) { double x1WC = x - d * dx / 2, x2WC = x + d * dx / 2; double y1WC = y - d * dy / 2, y2WC = y + d * dy / 2; if (my z[i][j] > 0) { Graphics_setColour (g, Graphics_WHITE); } Graphics_fillRectangle (g, x1WC, x2WC, y1WC, y2WC); Graphics_setColour (g, colour); Graphics_rectangle (g, x1WC, x2WC , y1WC, y2WC); } } } Graphics_setGrey (g, 0.0); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); if (ymin * ymax < 0.0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_marksBottom (g, 2, true, true, false); if (xmin * xmax < 0.0) { Graphics_markBottom (g, 0.0, true, true, true, nullptr); } } }
static void logo_defaultDraw (Graphics g) { Graphics_setColour (g, Graphics_MAGENTA); Graphics_fillRectangle (g, 0, 1, 0, 1); Graphics_setGrey (g, 0.5); Graphics_fillRectangle (g, 0.05, 0.95, 0.1, 0.9); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setColour (g, Graphics_YELLOW); Graphics_setFont (g, kGraphics_font_TIMES); Graphics_setFontSize (g, 24); Graphics_setFontStyle (g, Graphics_ITALIC); Graphics_setUnderscoreIsSubscript (g, false); // because program names may contain underscores Graphics_text (g, 0.5, 0.6, praatP.title); Graphics_setFontStyle (g, 0); Graphics_setFontSize (g, 12); Graphics_text (g, 0.5, 0.25, U"\\s{Built on the} %%Praat shell%\\s{,© Paul Boersma, 1992-2015"); }
void TableOfReal_drawAsSquares (TableOfReal me, Graphics graphics, long rowmin, long rowmax, long colmin, long colmax, int garnish) { double dx = 1, dy = 1; Graphics_Colour colour = Graphics_inqColour (graphics); fixRows (me, & rowmin, & rowmax); fixColumns (me, & colmin, & colmax); Graphics_setInner (graphics); Graphics_setWindow (graphics, colmin - 0.5, colmax + 0.5, rowmin - 0.5, rowmax + 0.5); double datamax = my data [rowmin] [colmin]; for (long irow = 1; irow <= my numberOfRows; irow ++) for (long icol = 1; icol <= my numberOfColumns; icol ++) if (fabs (my data [irow] [icol]) > datamax) datamax = fabs (my data [irow] [icol]); for (long irow = rowmin; irow <= rowmax; irow ++) { double y = rowmax + rowmin - irow; for (long icol = colmin; icol <= colmax; icol ++) { double x = icol; /* two neighbouring squares should not touch -> 0.95 */ double d = 0.95 * sqrt (fabs (my data [irow] [icol]) / datamax); double x1WC = x - d * dx / 2, x2WC = x + d * dx / 2; double y1WC = y - d * dy / 2, y2WC = y + d * dy / 2; if (my data [irow] [icol] > 0) Graphics_setColour (graphics, Graphics_WHITE); Graphics_fillRectangle (graphics, x1WC, x2WC, y1WC, y2WC); Graphics_setColour (graphics, colour); Graphics_rectangle (graphics, x1WC, x2WC , y1WC, y2WC); } } Graphics_setGrey (graphics, 0.0); Graphics_unsetInner (graphics); if (garnish) { for (long irow = rowmin; irow <= rowmax; irow ++) if (my rowLabels [irow]) Graphics_markLeft (graphics, rowmax + rowmin - irow, 0, 0, 0, my rowLabels [irow]); for (long icol = colmin; icol <= colmax; icol ++) if (my columnLabels [icol]) Graphics_markTop (graphics, icol, 0, 0, 0, my columnLabels [icol]); } }
static void gui_drawingarea_cb_expose (I, GuiDrawingAreaExposeEvent event) { iam (RunnerMFC); Melder_assert (event -> widget == my d_drawingArea); if (my graphics == NULL) return; // Could be the case in the very beginning. ExperimentMFC experiment = (ExperimentMFC) my data; long iresponse; if (my data == NULL) return; Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); if (experiment -> trial == 0) { Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (my graphics, 24); Graphics_text (my graphics, 0.5, 0.5, experiment -> startText); } else if (experiment -> pausing) { Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (my graphics, 24); Graphics_text (my graphics, 0.5, 0.5, experiment -> pauseText); if (experiment -> oops_right > experiment -> oops_left && experiment -> trial > 1) { drawControlButton (me, experiment -> oops_left, experiment -> oops_right, experiment -> oops_bottom, experiment -> oops_top, experiment -> oops_label); } } else if (experiment -> trial <= experiment -> numberOfTrials) { const wchar_t *visibleText = experiment -> stimulus [experiment -> stimuli [experiment -> trial]]. visibleText; wchar_t *visibleText_dup = Melder_wcsdup_f (visibleText ? visibleText : L""), *visibleText_p = visibleText_dup; Graphics_setFont (my graphics, kGraphics_font_TIMES); Graphics_setFontSize (my graphics, 10); Graphics_setColour (my graphics, Graphics_BLACK); Graphics_setTextAlignment (my graphics, Graphics_LEFT, Graphics_TOP); Graphics_text3 (my graphics, 0, 1, Melder_integer (experiment -> trial), L" / ", Melder_integer (experiment -> numberOfTrials)); Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_TOP); Graphics_setFontSize (my graphics, 24); /* * The run text. */ if (visibleText_p [0] != '\0') { wchar_t *visibleText_q = wcschr (visibleText_p, '|'); if (visibleText_q) *visibleText_q = '\0'; Graphics_text (my graphics, 0.5, 1.0, visibleText_p [0] != '\0' ? visibleText_p : experiment -> runText); if (visibleText_q) visibleText_p = visibleText_q + 1; else visibleText_p += wcslen (visibleText_p); } else { Graphics_text (my graphics, 0.5, 1.0, experiment -> runText); } Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); for (iresponse = 1; iresponse <= experiment -> numberOfDifferentResponses; iresponse ++) { ResponseMFC response = & experiment -> response [iresponse]; wchar_t *textToDraw = response -> label; // can be overridden if (visibleText_p [0] != '\0') { wchar_t *visibleText_q = wcschr (visibleText_p, '|'); if (visibleText_q) *visibleText_q = '\0'; textToDraw = visibleText_p; // override if (visibleText_q) visibleText_p = visibleText_q + 1; else visibleText_p += wcslen (visibleText_p); } if (wcsnequ (textToDraw, L"\\FI", 3)) { structMelderFile file; MelderDir_relativePathToFile (& experiment -> rootDirectory, textToDraw + 3, & file); Graphics_imageFromFile (my graphics, Melder_fileToPath (& file), response -> left, response -> right, response -> bottom, response -> top); } else { Graphics_setColour (my graphics, response -> name [0] == '\0' ? Graphics_SILVER : experiment -> responses [experiment -> trial] == iresponse ? Graphics_RED : experiment -> ok_right > experiment -> ok_left || experiment -> responses [experiment -> trial] == 0 ? Graphics_YELLOW : Graphics_SILVER); Graphics_setLineWidth (my graphics, 3.0); Graphics_fillRectangle (my graphics, response -> left, response -> right, response -> bottom, response -> top); Graphics_setColour (my graphics, Graphics_MAROON); Graphics_rectangle (my graphics, response -> left, response -> right, response -> bottom, response -> top); Graphics_setFontSize (my graphics, response -> fontSize ? response -> fontSize : 24); Graphics_text (my graphics, 0.5 * (response -> left + response -> right), 0.5 * (response -> bottom + response -> top), textToDraw); } Graphics_setFontSize (my graphics, 24); } for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC goodness = & experiment -> goodness [iresponse]; Graphics_setColour (my graphics, experiment -> responses [experiment -> trial] == 0 ? Graphics_SILVER : experiment -> goodnesses [experiment -> trial] == iresponse ? Graphics_RED : Graphics_YELLOW); Graphics_setLineWidth (my graphics, 3.0); Graphics_fillRectangle (my graphics, goodness -> left, goodness -> right, goodness -> bottom, goodness -> top); Graphics_setColour (my graphics, Graphics_MAROON); Graphics_rectangle (my graphics, goodness -> left, goodness -> right, goodness -> bottom, goodness -> top); Graphics_text (my graphics, 0.5 * (goodness -> left + goodness -> right), 0.5 * (goodness -> bottom + goodness -> top), goodness -> label); } if (experiment -> replay_right > experiment -> replay_left && my numberOfReplays < experiment -> maximumNumberOfReplays) { drawControlButton (me, experiment -> replay_left, experiment -> replay_right, experiment -> replay_bottom, experiment -> replay_top, experiment -> replay_label); } if (experiment -> ok_right > experiment -> ok_left && experiment -> responses [experiment -> trial] != 0 && (experiment -> numberOfGoodnessCategories == 0 || experiment -> goodnesses [experiment -> trial] != 0)) { drawControlButton (me, experiment -> ok_left, experiment -> ok_right, experiment -> ok_bottom, experiment -> ok_top, experiment -> ok_label); } if (experiment -> oops_right > experiment -> oops_left && experiment -> trial > 1) { drawControlButton (me, experiment -> oops_left, experiment -> oops_right, experiment -> oops_bottom, experiment -> oops_top, experiment -> oops_label); } Melder_free (visibleText_dup); } else { Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (my graphics, 24); Graphics_text (my graphics, 0.5, 0.5, experiment -> endText); if (experiment -> oops_right > experiment -> oops_left && experiment -> trial > 1) { drawControlButton (me, experiment -> oops_left, experiment -> oops_right, experiment -> oops_bottom, experiment -> oops_top, experiment -> oops_label); } } }
static void gui_drawingarea_cb_click (I, GuiDrawingAreaClickEvent event) { iam (RunnerMFC); if (my graphics == NULL) return; // Could be the case in the very beginning. ExperimentMFC experiment = (ExperimentMFC) my data; if (my data == NULL) return; double reactionTime = Melder_clock () - experiment -> startingTime; if (! experiment -> blankWhilePlaying) reactionTime -= experiment -> stimulusInitialSilenceDuration; double x, y; Graphics_DCtoWC (my graphics, event -> x, event -> y, & x, & y); if (experiment -> trial == 0) { // the first click of the experiment experiment -> trial ++; my broadcastDataChanged (); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { if (experiment -> numberOfTrials < 1) { Melder_flushError ("There are zero trials in this experiment."); forget (me); return; } autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [1]); // works only if there is at least one trial } } else if (experiment -> pausing) { // a click to leave the break if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top && experiment -> trial > 1) { do_oops (me); } else { experiment -> pausing = FALSE; experiment -> trial ++; my broadcastDataChanged (); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } } } else if (experiment -> trial <= experiment -> numberOfTrials) { long iresponse; if (x > experiment -> ok_left && x < experiment -> ok_right && y > experiment -> ok_bottom && y < experiment -> ok_top && experiment -> responses [experiment -> trial] != 0 && (experiment -> numberOfGoodnessCategories == 0 || experiment -> goodnesses [experiment -> trial] != 0)) { do_ok (me); } else if (x > experiment -> replay_left && x < experiment -> replay_right && y > experiment -> replay_bottom && y < experiment -> replay_top && my numberOfReplays < experiment -> maximumNumberOfReplays) { do_replay (me); } else if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top && experiment -> trial > 1) { do_oops (me); } else if (experiment -> responses [experiment -> trial] == 0 || experiment -> ok_right > experiment -> ok_left) { for (iresponse = 1; iresponse <= experiment -> numberOfDifferentResponses; iresponse ++) { ResponseMFC response = & experiment -> response [iresponse]; if (x > response -> left && x < response -> right && y > response -> bottom && y < response -> top && response -> name [0] != '\0') { experiment -> responses [experiment -> trial] = iresponse; experiment -> reactionTimes [experiment -> trial] = reactionTime; if (experiment -> responsesAreSounds) { ExperimentMFC_playResponse (experiment, iresponse); } if (experiment -> ok_right <= experiment -> ok_left && experiment -> numberOfGoodnessCategories == 0) { do_ok (me); } else { my broadcastDataChanged (); Graphics_updateWs (my graphics); } } } if (experiment -> responses [experiment -> trial] != 0 && experiment -> ok_right > experiment -> ok_left) { for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC cat = & experiment -> goodness [iresponse]; if (x > cat -> left && x < cat -> right && y > cat -> bottom && y < cat -> top) { experiment -> goodnesses [experiment -> trial] = iresponse; my broadcastDataChanged (); Graphics_updateWs (my graphics); } } } } else if (experiment -> responses [experiment -> trial] != 0) { Melder_assert (experiment -> ok_right <= experiment -> ok_left); for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC cat = & experiment -> goodness [iresponse]; if (x > cat -> left && x < cat -> right && y > cat -> bottom && y < cat -> top) { experiment -> goodnesses [experiment -> trial] = iresponse; do_ok (me); } } } } else { if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top) { do_oops (me); return; } if (my iexperiment < my experiments -> size) { my iexperiment ++; if (! RunnerMFC_startExperiment (me)) { Melder_flushError (NULL); forget (me); return; } } } }
void Graphics_surface (Graphics me, double **z, long ix1, long ix2, double x1, double x2, long iy1, long iy2, double y1, double y2, double minimum, double maximum, double elevation, double azimuth) { double dx, dy; /* 'sum' is the running sum of the x and y indices of the back corner of each tetragon. * The x and y indices of the back corner of the backmost tetragon are ix2 and iy2, * The x and y indices of the front corner of the frontmost tetragon are ix1 and iy1, * so that the x and y indices of its back corner are ix1 + 1 and iy1 + 1. */ long maxsum = ix2 + iy2, minsum = (ix1 + 1) + (iy1 + 1), sum; (void) elevation; /* BUG */ (void) azimuth; /* BUG */ if (ix2 <= ix1 || iy2 <= iy1) return; dx = (x2 - x1) / (ix2 - ix1); dy = (y2 - y1) / (iy2 - iy1); /* We start at the back of the surface plot. * This part of the picture may be overdrawn by points more forward. */ for (sum = maxsum; sum >= minsum; sum --) { /* We are going to cycle over a diagonal sequence of points. * Compute the row boundaries of this sequence. */ long iymin = iy1 + 1, iymax = iy2, iy; if (iymin < sum - ix2) iymin = sum - ix2; if (iymax > sum - (ix1 + 1)) iymax = sum - (ix1 + 1); for (iy = iymin; iy <= iymax; iy ++) { /* Compute the indices of all four points. */ long ix = sum - iy; long ixback = ix, ixfront = ix - 1, ixleft = ix - 1, ixright = ix; long iyback = iy, iyfront = iy - 1, iyleft = iy, iyright = iy - 1; /* Compute the world coordinates of all four points. */ double xback = x1 + (ixback - ix1) * dx, xright = xback; double xfront = x1 + (ixfront - ix1) * dx, xleft = xfront; double yback = y1 + (iyback - iy1) * dy, yleft = yback; double yfront = y1 + (iyfront - iy1) * dy, yright = yfront; double zback = z [iyback] [ixback], zfront = z [iyfront] [ixfront]; double zleft = z [iyleft] [ixleft], zright = z [iyright] [ixright]; /* The Graphics library uses a two-dimensional world, so we have to convert * to 2-D world coordinates, which we call x [0..3] and y [0..3]. * We suppose that world coordinate "x" = 0 is in the centre of the figure, * and that the left and right borders of the figure have world coordinates -1 and +1. * Also, we suppose that the bottom and top are around 'minimum' and 'maximum'. */ double x [5], y [5]; /* Elevation and azimuth fixed??? */ double up = 0.3 * (maximum - minimum), xscale = 1 / (x2 - x1), yscale = 1 / (y2 - y1); /* The back point. */ x [0] = (xback - x1) * xscale - (yback - y1) * yscale; y [0] = up * ((xback - x1) * xscale + (yback - y1) * yscale) + zback; /* The right point. */ x [1] = (xright - x1) * xscale - (yright - y1) * yscale; y [1] = up * ((xright - x1) * xscale + (yright - y1) * yscale) + zright; /* The front point. */ x [2] = (xfront - x1) * xscale - (yfront - y1) * yscale; y [2] = up * ((xfront - x1) * xscale + (yfront - y1) * yscale) + zfront; /* The left point. */ x [3] = (xleft - x1) * xscale - (yleft - y1) * yscale; y [3] = up * ((xleft - x1) * xscale + (yleft - y1) * yscale) + zleft; /* Paint the tetragon in the average grey value, white at the top. * This gives the idea of height. */ Graphics_setGrey (me, (0.25 * (zback + zright + zfront + zleft) - minimum) / (maximum - minimum)); Graphics_fillArea (me, 4, & x [0], & y [0]); /* Draw the borders of the tetragon in black. * This gives the idea of steepness and viewing angle. */ Graphics_setGrey (me, 0); x [4] = x [0]; y [4] = y [0]; /* Close polygon. */ Graphics_polyline (me, 5, & x [0], & y [0]); } } }
void structERPWindow :: v_drawSelectionViewer () { ERP erp = (ERP) data; Graphics_setWindow (d_graphics, -1.1, 1.1, -1.01, 1.19); Graphics_setGrey (d_graphics, 0.85); Graphics_fillRectangle (d_graphics, -1.1, 1.1, -1.01, 1.19); Graphics_setColour (d_graphics, Graphics_BLACK); long numberOfDrawableChannels = erp -> ny >= 64 && Melder_wcsequ (erp -> d_channelNames [64], L"O2") ? 64 : erp -> ny >= 32 && Melder_wcsequ (erp -> d_channelNames [32], L"Cz") ? 32 : 0; BiosemiLocationData *biosemiLocationData = numberOfDrawableChannels == 64 ? biosemiCapCoordinates64 : numberOfDrawableChannels == 32 ? biosemiCapCoordinates32 : 0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double inclination = (double) biosemiLocationData [ichan]. inclination; double azimuth = (double) biosemiLocationData [ichan]. azimuth; bool rightHemisphere = inclination >= 0.0; double r = fabs (inclination / 115.0); double theta = rightHemisphere ? azimuth * (NUMpi / 180.0) : (azimuth + 180.0) * (NUMpi / 180.0); biosemiLocationData [ichan]. topX = r * cos (theta); biosemiLocationData [ichan]. topY = r * sin (theta); } long n = 201; double d = 2.0 / (n - 1); autoNUMvector <double> mean (1, numberOfDrawableChannels); for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { mean [ichan] = d_startSelection == d_endSelection ? Sampled_getValueAtX (erp, d_startSelection, ichan, 0, true) : Vector_getMean (erp, d_startSelection, d_endSelection, ichan); } autoNUMmatrix <double> image (1, n, 1, n); for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y <= 1.0) { double value = NUMundefined, sum = 0.0, weight = 0.0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double dx = x - biosemiLocationData [ichan]. topX; double dy = y - biosemiLocationData [ichan]. topY; double distance = sqrt (dx * dx + dy * dy); if (distance < 1e-12) { value = mean [ichan]; break; } distance = distance * distance * distance * distance * distance * distance; sum += mean [ichan] / distance; weight += 1.0 / distance; } if (value == NUMundefined) value = ( sum == 0.0 ? 0.0 : sum / weight ); image [irow] [icol] = value; } } } double minimum = 0.0, maximum = 0.0; for (long irow = 1; irow <= n; irow ++) { for (long icol = 1; icol <= n; icol ++) { double value = image [irow] [icol]; if (value < minimum) minimum = value; else if (value > maximum) maximum = value; } } double absoluteExtremum = - minimum > maximum ? - minimum : maximum; if (d_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_RANGE) { minimum = d_sound_scaling_minimum; maximum = d_sound_scaling_maximum; } else if (d_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_HEIGHT) { double mean = 0.5 * (minimum + maximum); minimum = mean - 0.5 * d_sound_scaling_height; maximum = mean + 0.5 * d_sound_scaling_height; } else { minimum = - absoluteExtremum; maximum = absoluteExtremum; } for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y > 1.0) { image [irow] [icol] = minimum + 0.1875 * (maximum - minimum); // -0.625 * absoluteExtremum; } } } Graphics_image (d_graphics, image.peek(), 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum); Graphics_setLineWidth (d_graphics, 2.0); /* * Nose. */ Graphics_setGrey (d_graphics, 0.5); {// scope double x [3] = { -0.08, 0.0, 0.08 }, y [3] = { 0.99, 1.18, 0.99 }; Graphics_fillArea (d_graphics, 3, x, y); } Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_line (d_graphics, -0.08, 0.99, 0.0, 1.18); Graphics_line (d_graphics, 0.08, 0.99, 0.0, 1.18); /* * Ears. */ Graphics_setGrey (d_graphics, 0.5); Graphics_fillRectangle (d_graphics, -1.09, -1.00, -0.08, 0.08); Graphics_fillRectangle (d_graphics, 1.09, 1.00, -0.08, 0.08); Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_line (d_graphics, -0.99, 0.08, -1.09, 0.08); Graphics_line (d_graphics, -1.09, 0.08, -1.09, -0.08); Graphics_line (d_graphics, -1.09, -0.08, -0.99, -0.08); Graphics_line (d_graphics, 0.99, 0.08, 1.09, 0.08); Graphics_line (d_graphics, 1.09, 0.08, 1.09, -0.08); Graphics_line (d_graphics, 1.09, -0.08, 0.99, -0.08); /* * Scalp. */ Graphics_ellipse (d_graphics, -1.0, 1.0, -1.0, 1.0); Graphics_setLineWidth (d_graphics, 1.0); }
void structERP :: f_drawScalp (Graphics graphics, double tmin, double tmax, double vmin, double vmax, bool garnish) { Graphics_setInner (graphics); Graphics_setWindow (graphics, -1.0, 1.0, -1.0, 1.0); //Graphics_setGrey (graphics, 1.0); //Graphics_fillRectangle (graphics, -1.1, 1.1, -1.01, 1.19); //Graphics_setColour (graphics, Graphics_BLACK); long numberOfDrawableChannels = this -> ny >= 64 && Melder_wcsequ (this -> d_channelNames [64], L"O2") ? 64 : this -> ny >= 32 && Melder_wcsequ (this -> d_channelNames [32], L"Cz") ? 32 : 0; BiosemiLocationData *biosemiLocationData = numberOfDrawableChannels == 64 ? biosemiCapCoordinates64 : numberOfDrawableChannels == 32 ? biosemiCapCoordinates32 : 0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double inclination = (double) biosemiLocationData [ichan]. inclination; double azimuth = (double) biosemiLocationData [ichan]. azimuth; bool rightHemisphere = inclination >= 0.0; double r = fabs (inclination / 115.0); double theta = rightHemisphere ? azimuth * (NUMpi / 180.0) : (azimuth + 180.0) * (NUMpi / 180.0); biosemiLocationData [ichan]. topX = r * cos (theta); biosemiLocationData [ichan]. topY = r * sin (theta); } long n = 201; double d = 2.0 / (n - 1); autoNUMvector <double> mean (1, numberOfDrawableChannels); for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { mean [ichan] = tmin == tmax ? Sampled_getValueAtX (this, tmin, ichan, 0, true) : Vector_getMean (this, tmin, tmax, ichan); } autoNUMmatrix <double> image (1, n, 1, n); for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y <= 1.0) { double value = NUMundefined, sum = 0.0, weight = 0.0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double dx = x - biosemiLocationData [ichan]. topX; double dy = y - biosemiLocationData [ichan]. topY; double distance = sqrt (dx * dx + dy * dy); if (distance < 1e-12) { value = mean [ichan]; break; } distance = distance * distance * distance * distance * distance * distance; sum += mean [ichan] / distance; weight += 1.0 / distance; } if (value == NUMundefined) value = ( sum == 0.0 ? 0.0 : sum / weight ); image [irow] [icol] = value; } } } for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y > 1.0) { image [irow] [icol] = vmin; } } } Graphics_image (graphics, image.peek(), 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, vmin, vmax); Graphics_setLineWidth (graphics, 2.0); /* * Nose. */ Graphics_setGrey (graphics, 0.5); {// scope double x [3] = { -0.08, 0.0, 0.08 }, y [3] = { 0.99, 1.18, 0.99 }; Graphics_fillArea (graphics, 3, x, y); } Graphics_setColour (graphics, Graphics_BLACK); Graphics_line (graphics, -0.08, 0.99, 0.0, 1.18); Graphics_line (graphics, 0.08, 0.99, 0.0, 1.18); /* * Ears. */ Graphics_setGrey (graphics, 0.5); Graphics_fillRectangle (graphics, -1.09, -1.00, -0.08, 0.08); Graphics_fillRectangle (graphics, 1.09, 1.00, -0.08, 0.08); Graphics_setColour (graphics, Graphics_BLACK); Graphics_line (graphics, -0.99, 0.08, -1.09, 0.08); Graphics_line (graphics, -1.09, 0.08, -1.09, -0.08); Graphics_line (graphics, -1.09, -0.08, -0.99, -0.08); Graphics_line (graphics, 0.99, 0.08, 1.09, 0.08); Graphics_line (graphics, 1.09, 0.08, 1.09, -0.08); Graphics_line (graphics, 1.09, -0.08, 0.99, -0.08); /* * Scalp. */ Graphics_ellipse (graphics, -1.0, 1.0, -1.0, 1.0); Graphics_setLineWidth (graphics, 1.0); Graphics_unsetInner (graphics); if (garnish) { autoNUMmatrix <double> legend (1, n, 1, 2); for (long irow = 1; irow <= n; irow ++) { for (long icol = 1; icol <= 2; icol ++) { legend [irow] [icol] = (irow - 1) / (n - 1.0); } } Graphics_image (graphics, legend.peek(), 1, 2, 0.78, 0.98, 1, n, -0.8, +0.8, 0.0, 1.0); Graphics_rectangle (graphics, 0.78, 0.98, -0.8, +0.8); Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text2 (graphics, 1.0, -0.8, Melder_double (vmin * 1e6), L" \\muV"); Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_BOTTOM); Graphics_text2 (graphics, 1.0, +0.8, Melder_double (vmax * 1e6), L" \\muV"); } }
static void smallGrey (void) { int row, col, i; numberOfEdgeContours = 0; numberOfClosedContours = 0; for (iBorder = 1; iBorder <= numberOfBorders; iBorder ++) { for (row = 0; row < MAXGREYSIDE; row ++) for (col = 0; col < MAXGREYSIDE; col ++) right [row] [col] = below [row] [col] = 0; /* Find all the edge contours of this border value. */ for (col = col1; col < col2; col ++) if (empty (row1, col, 1)) makeEdgeContour (row1, col, 1); for (row = row1; row < row2; row ++) if (empty (row, col2 - 1, 2)) makeEdgeContour (row, col2 - 1, 2); for (col = col2 - 1; col >= col1; col --) if (empty (row2 - 1, col, 3)) makeEdgeContour (row2 - 1, col, 3); for (row = row2 - 1; row >= row1; row --) if (empty (row, col1, 4)) makeEdgeContour (row, col1, 4); /* Find all the closed contours of this border value. */ for (row = row1 + 1; row < row2; row ++) for (col = col1; col < col2; col ++) if (empty (row, col, 1)) makeClosedContour (row, col, 1); for (col = col1 + 1; col < col2; col ++) for (row = row1; row < row2; row ++) if (empty (row, col, 4)) makeClosedContour (row, col, 4); } numberOfEdgePoints = 2 * numberOfEdgeContours + 4; Melder_assert (numberOfEdgePoints <= MAXGREYEDGEPOINTS * numberOfBorders); /* Make a list of all points on the edge. */ /* The edge points include the four corner points. */ for (i = 1; i <= 4; i ++) { EdgePoint p = & edgePoints [i]; p -> ori = i; p -> val = 0; p -> iContour = 0; p -> start = 0; p -> usedAsEntry = 0; p -> grey = -1; } /* The edge points include the first points of the edge contours. */ for (i = 1; i <= numberOfEdgeContours; i ++) { EdgeContour c = edgeContours [i]; EdgePoint p = & edgePoints [i + i + 3]; switch (p -> ori = c -> beginOri) { case 1: p -> val = c -> x [1] - xoff - col1 * dx; break; case 2: p -> val = c -> y [1] - yoff - row1 * dy; break; case 3: p -> val = xoff + col2 * dx - c -> x [1]; break; case 4: p -> val = yoff + row2 * dy - c -> y [1]; break; } p -> iContour = i; p -> start = 1; p -> usedAsEntry = 0; p -> grey = c -> lowerGrey; } /* The edge points include the last points of the edge contours. */ for (i = 1; i <= numberOfEdgeContours; i ++) { EdgeContour c = edgeContours [i]; EdgePoint p = & edgePoints [i + i + 4]; switch (p -> ori = c -> endOri) { case 1: p -> val = c -> x [c -> numberOfPoints] - xoff - col1 * dx; break; case 2: p -> val = c -> y [c -> numberOfPoints] - yoff - row1 * dy; break; case 3: p -> val = xoff + col2 * dx - c -> x [c -> numberOfPoints]; break; case 4: p -> val = yoff + row2 * dy - c -> y [c -> numberOfPoints]; break; } p -> iContour = i; p -> start = 0; p -> usedAsEntry = 0; p -> grey = c -> upperGrey; } /* Sort the list of edge points with keys Ori and Val. */ { int i; for (i = 1; i < numberOfEdgePoints; i ++) { structEdgePoint p; int min = i, j; for (j = i + 1; j <= numberOfEdgePoints; j ++) if (edgePoints [min]. ori > edgePoints [j]. ori || (edgePoints [min]. ori == edgePoints [j]. ori && edgePoints [min]. val > edgePoints [j]. val)) min = j; p = edgePoints [i]; edgePoints [i] = edgePoints [min]; edgePoints [min] = p; } } { int edge0, edge1, darkness; for (edge0 = 1; edge0 <= numberOfEdgePoints; edge0 ++) if (edgePoints [edge0].grey > -1 && ! edgePoints [edge0].usedAsEntry) { int iPoint = 0; edge1 = edge0; do { /* Follow one edge contour. */ EdgePoint p = & edgePoints [edge1]; int iContour = p -> iContour; EdgeContour c = edgeContours [iContour]; Melder_assert (iContour > 0); darkness = p -> grey; p -> usedAsEntry = 1; if (p -> start) { for (i = 1; i <= c -> numberOfPoints; i ++) { Melder_assert (iPoint < MAXGREYPATH); x [++ iPoint] = c -> x [i]; y [iPoint] = c -> y [i]; } for (i = edge1 + 1; i <= numberOfEdgePoints; i ++) if (edgePoints [i].iContour == iContour) edge1 = i; } else { int edge1dummy = edge1; for (i = c -> numberOfPoints; i >= 1; i --) { Melder_assert (iPoint < MAXGREYPATH); x [++ iPoint] = c -> x [i]; y [iPoint] = c -> y [i]; } for (i = 1; i <= edge1dummy - 1; i ++) if (edgePoints [i].iContour == iContour) edge1 = i; } edge1 = edge1 % numberOfEdgePoints + 1; /* Round some corners. */ while (edgePoints [edge1].grey == -1) { ++ iPoint; Melder_assert (iPoint <= MAXGREYPATH); switch (edgePoints [edge1].ori) { case 1: x [iPoint] = xoff + col1 * dx; y [iPoint] = yoff + row1 * dy; break; case 2: x [iPoint] = xoff + col2 * dx; y [iPoint] = yoff + row1 * dy; break; case 3: x [iPoint] = xoff + col2 * dx; y [iPoint] = yoff + row2 * dy; break; case 4: x [iPoint] = xoff + col1 * dx; y [iPoint] = yoff + row2 * dy; break; } edge1 = edge1 % numberOfEdgePoints + 1; } } while (edge1 != edge0); fillGrey (iPoint, x, y, darkness); } } if (numberOfEdgeContours == 0) { int i = 1; while (i <= numberOfBorders && border [i] < data [row1] [col1]) i ++; x [1] = x [4] = xoff + col1 * dx; x [2] = x [3] = xoff + col2 * dx; y [1] = y [2] = yoff + row1 * dy; y [3] = y [4] = yoff + row2 * dy; fillGrey (4, x, y, i); } /* Iterate over all the closed contours. * Those that are not enclosed by any other contour, are filled first. */ { int enclosed, found; do { found = 0; for (i = 1; i <= numberOfClosedContours; i ++) { ClosedContour ci = closedContours [i]; if (! ci -> drawn) { int j = 1; enclosed = 0; while (j <= numberOfClosedContours && ! enclosed) { ClosedContour cj = closedContours [j]; if ((! cj -> drawn) && j != i && ci -> xmin > cj -> xmin && ci -> xmax < cj -> xmax && ci -> ymin > cj -> ymin && ci -> ymax < cj -> ymax) enclosed = NUMrotationsPointInPolygon (ci -> x [1], ci -> y [1], cj -> numberOfPoints, cj -> x, cj -> y); j ++; } if (enclosed == 0) { found = 1; fillGrey (ci -> numberOfPoints, ci -> x, ci -> y, ci -> grey); ci -> drawn = 1; } } } } while (found); } Graphics_setGrey (theGraphics, 0.0); for (i = 1; i <= numberOfEdgeContours; i ++) EdgeContour_delete (edgeContours [i]); for (i = 1; i <= numberOfClosedContours; i ++) ClosedContour_delete (closedContours [i]); }
static void fillGrey (int numberOfPoints, double *x, double *y, int igrey) /* "igrey" is in between 1 and numberOfBorders + 1. */ { Graphics_setGrey (theGraphics, 1.0 - (igrey - 1.0) / numberOfBorders); Graphics_fillArea (theGraphics, numberOfPoints, & x [1], & y [1]); }