Polygon Sound_to_Polygon (Sound me, int channel, double tmin, double tmax, double ymin, double ymax, double level) { try { bool clip = ymin < ymax; if (channel < 1 || channel > my ny) { Melder_throw ("Channel does not exist."); } if (tmin >= tmax) { tmin = my xmin; tmax = my xmax; } if (tmin < my xmin) { tmin = my xmin; } if (tmax > my xmax) { tmax = my xmax; } if (tmin >= my xmax || tmax < my xmin) { Melder_throw ("Invalid domain."); } long k = 1, i1 = Sampled_xToHighIndex (me, tmin); long i2 = Sampled_xToLowIndex (me, tmax); long numberOfPoints = i2 - i1 + 1 + 2 + 2; // begin + endpoint + level autoPolygon him = Polygon_create (numberOfPoints); /* In Vector_getValueAtX the interpolation only returns defined values between the left and right edges that are calculated as left = x1 - 0.5 * dx; right = left + my nx * dx. Given a sound, for example on the domain [0,...], the value of 'left' with the above formula might not return exactly xmin but instead a very small deviation (due to the imprecise representation of real numbers in a computer). Querying for the value at xmin which is outside the interpolation domain then produces an 'undefined'. We try to avoid this with the following workaround. */ double xmin = my x1 - 0.5 * my dx; double xmax = xmin + my nx * my dx; tmin = tmin < xmin ? xmin : tmin; tmax = tmax > xmax ? xmax : tmax; // End of workaround his x[k] = tmin; his y[k++] = CLIP_Y (level, ymin, ymax); his x[k] = tmin; double y = Vector_getValueAtX (me, tmin, channel, Vector_VALUE_INTERPOLATION_LINEAR); his y[k++] = CLIP_Y (y, ymin, ymax); for (long i = i1; i <= i2; i++) { y = my z[channel][i]; his x[k] = my x1 + (i - 1) * my dx; his y[k++] = CLIP_Y (y, ymin, ymax); } his x[k] = tmax; y = Vector_getValueAtX (me, tmax, channel, Vector_VALUE_INTERPOLATION_LINEAR); his y[k++] = CLIP_Y (y, ymin, ymax); his x[k] = tmax; his y[k++] = CLIP_Y (level, ymin, ymax); return him.transfer(); } catch (MelderError) { Melder_throw (me, ":no Polygon created."); } }
/********************************************************************* * * LCD_DrawVLine */ void LCD_DrawVLine(int x, int y0, int y1) { /* Perform clipping and check if there is something to do */ RETURN_IF_X_OUT(); CLIP_Y(); if (y1 < y0) { return; } /* Call driver to draw */ LCDDEV_L0_DrawVLine(x, y0, y1); }
void LCD_FillRect(int x0, int y0, int x1, int y1) { /* Perform clipping and check if there is something to do */ CLIP_X(); if (x1<x0) return; CLIP_Y(); if (y1<y0) return; /* Call driver to draw */ LCDDEV_L0_FillRect(x0,y0,x1,y1); }
Polygon Sounds_to_Polygon_enclosed (Sound me, Sound thee, int channel, double tmin, double tmax, double ymin, double ymax) { try { bool clip = ymin < ymax; if (my ny > 1 && thy ny > 1 && my ny != thy ny) { Melder_throw ("The numbers of channels of the two sounds have to be equal or 1."); } long numberOfChannels = my ny > thy ny ? my ny : thy ny; if (channel < 1 || channel > numberOfChannels) { Melder_throw ("Channel does not exist."); } // find overlap in the domains with xmin workaround as in Sound_to_Polygon double xmin1 = my x1 - 0.5 * my dx, xmin2 = thy x1 - 0.5 * thy dx ; double xmin = my xmin > thy xmin ? xmin1 : xmin2; double xmax = my xmax < thy xmax ? xmin1 + my nx * my dx : xmin2 + thy nx * thy dx; if (xmax <= xmin) { Melder_throw ("Domains must overlap."); } if (tmin >= tmax) { tmin = xmin; tmax = xmax; } if (tmin < xmin) { tmin = xmin; } if (tmax > xmax) { tmax = xmax; } if (tmin >= xmax || tmax < xmin) { Melder_throw ("Invalid domain."); } long k = 1; long ib1 = Sampled_xToHighIndex (me, tmin); long ie1 = Sampled_xToLowIndex (me, tmax); long n1 = ie1 - ib1 + 1; long ib2 = Sampled_xToHighIndex (thee, tmin); long ie2 = Sampled_xToLowIndex (thee, tmax); long n2 = ie2 - ib2 + 1; long numberOfPoints = n1 + n2 + 4; // me + thee + begin + endpoint + closing autoPolygon him = Polygon_create (numberOfPoints); // my starting point at tmin double y = Vector_getValueAtX (me, tmin, (my ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmin; his y[k++] = CLIP_Y (y, ymin, ymax); // my samples for (long i = ib1; i <= ie1; i++) { double t = my x1 + (i - 1) * my dx; y = my z[my ny == 1 ? 1 : channel][i]; his x[k] = t; his y[k++] = CLIP_Y (y, ymin, ymax); } // my end point at tmax y = Vector_getValueAtX (me, tmax, (my ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmax; his y[k++] = y; // thy starting point at tmax y = Vector_getValueAtX (thee, tmax, (thy ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmax; his y[k++] = y; // thy samples for (long i = ie2; i >= ib2; i--) { double t = thy x1 + (i - 1) * thy dx; y = thy z[thy ny == 1 ? 1 : channel][i]; his x[k] = t; his y[k++] = CLIP_Y (y, ymin, ymax); } // thy end point at tmin y = Vector_getValueAtX (thee, tmin, (thy ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmin; his y[k] = y; Melder_assert (k == numberOfPoints); return him.transfer(); } catch (MelderError) { Melder_throw (me, ": no enclosed Polygon created."); } }