⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tkcanvarc.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 4 页
字号:
	    newDist = TkOvalToPoint(arcPtr->bbox, width, filled, pointPtr);	    if (newDist < dist) {		dist = newDist;	    }	}    } else {	if ((arcPtr->extent < -180.0) || (arcPtr->extent > 180.0)) {	    if (filled && (polyDist < dist)) {		dist = polyDist;	    }	}    }    return dist;}/* *-------------------------------------------------------------- * * ArcToArea -- * *	This procedure is called to determine whether an item *	lies entirely inside, entirely outside, or overlapping *	a given area. * * Results: *	-1 is returned if the item is entirely outside the area *	given by rectPtr, 0 if it overlaps, and 1 if it is entirely *	inside the given area. * * Side effects: *	None. * *-------------------------------------------------------------- */	/* ARGSUSED */static intArcToArea(canvas, itemPtr, rectPtr)    Tk_Canvas canvas;		/* Canvas containing item. */    Tk_Item *itemPtr;		/* Item to check against arc. */    double *rectPtr;		/* Pointer to array of four coordinates				 * (x1, y1, x2, y2) describing rectangular				 * area.  */{    ArcItem *arcPtr = (ArcItem *) itemPtr;    double rx, ry;		/* Radii for transformed oval:  these define				 * an oval centered at the origin. */    double tRect[4];		/* Transformed version of x1, y1, x2, y2,				 * for coord. system where arc is centered				 * on the origin. */    double center[2], width, angle, tmp;    double points[20], *pointPtr;    int numPoints, filled;    int inside;			/* Non-zero means every test so far suggests				 * that arc is inside rectangle.  0 means				 * every test so far shows arc to be outside				 * of rectangle. */    int newInside;    if ((arcPtr->fillGC != None) || (arcPtr->outlineGC == None)) {	filled = 1;    } else {	filled = 0;    }    if (arcPtr->outlineGC == None) {	width = 0.0;    } else {	width = arcPtr->width;    }    /*     * Transform both the arc and the rectangle so that the arc's oval     * is centered on the origin.     */    center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;    center[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;    tRect[0] = rectPtr[0] - center[0];    tRect[1] = rectPtr[1] - center[1];    tRect[2] = rectPtr[2] - center[0];    tRect[3] = rectPtr[3] - center[1];    rx = arcPtr->bbox[2] - center[0] + width/2.0;    ry = arcPtr->bbox[3] - center[1] + width/2.0;    /*     * Find the extreme points of the arc and see whether these are all     * inside the rectangle (in which case we're done), partly in and     * partly out (in which case we're done), or all outside (in which     * case we have more work to do).  The extreme points include the     * following, which are checked in order:     *     * 1. The outside points of the arc, corresponding to start and     *	  extent.     * 2. The center of the arc (but only in pie-slice mode).     * 3. The 12, 3, 6, and 9-o'clock positions (but only if the arc     *    includes those angles).     */    pointPtr = points;    angle = -arcPtr->start*(PI/180.0);    pointPtr[0] = rx*cos(angle);    pointPtr[1] = ry*sin(angle);    angle += -arcPtr->extent*(PI/180.0);    pointPtr[2] = rx*cos(angle);    pointPtr[3] = ry*sin(angle);    numPoints = 2;    pointPtr += 4;    if ((arcPtr->style == pieSliceUid) && (arcPtr->extent < 180.0)) {	pointPtr[0] = 0.0;	pointPtr[1] = 0.0;	numPoints++;	pointPtr += 2;    }    tmp = -arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	pointPtr[0] = rx;	pointPtr[1] = 0.0;	numPoints++;	pointPtr += 2;    }    tmp = 90.0 - arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	pointPtr[0] = 0.0;	pointPtr[1] = -ry;	numPoints++;	pointPtr += 2;    }    tmp = 180.0 - arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	pointPtr[0] = -rx;	pointPtr[1] = 0.0;	numPoints++;	pointPtr += 2;    }    tmp = 270.0 - arcPtr->start;    if (tmp < 0) {	tmp += 360.0;    }    if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {	pointPtr[0] = 0.0;	pointPtr[1] = ry;	numPoints++;    }    /*     * Now that we've located the extreme points, loop through them all     * to see which are inside the rectangle.     */    inside = (points[0] > tRect[0]) && (points[0] < tRect[2])	    && (points[1] > tRect[1]) && (points[1] < tRect[3]);    for (pointPtr = points+2; numPoints > 1; pointPtr += 2, numPoints--) {	newInside = (pointPtr[0] > tRect[0]) && (pointPtr[0] < tRect[2])		&& (pointPtr[1] > tRect[1]) && (pointPtr[1] < tRect[3]);	if (newInside != inside) {	    return 0;	}    }    if (inside) {	return 1;    }    /*     * So far, oval appears to be outside rectangle, but can't yet tell     * for sure.  Next, test each of the four sides of the rectangle     * against the bounding region for the arc.  If any intersections     * are found, then return "overlapping".  First, test against the     * polygon(s) forming the sides of a chord or pie-slice.     */    if (arcPtr->style == pieSliceUid) {	if (width >= 1.0) {	    if (TkPolygonToArea(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,		    rectPtr) != -1)  {		return 0;	    }	    if (TkPolygonToArea(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,		    PIE_OUTLINE2_PTS, rectPtr) != -1) {		return 0;	    }	} else {	    if ((TkLineToArea(center, arcPtr->center1, rectPtr) != -1) ||		    (TkLineToArea(center, arcPtr->center2, rectPtr) != -1)) {		return 0;	    }	}    } else if (arcPtr->style == chordUid) {	if (width >= 1.0) {	    if (TkPolygonToArea(arcPtr->outlinePtr, CHORD_OUTLINE_PTS,		    rectPtr) != -1) {		return 0;	    }	} else {	    if (TkLineToArea(arcPtr->center1, arcPtr->center2,		    rectPtr) != -1) {		return 0;	    }	}    }    /*     * Next check for overlap between each of the four sides and the     * outer perimiter of the arc.  If the arc isn't filled, then also     * check the inner perimeter of the arc.     */    if (HorizLineToArc(tRect[0], tRect[2], tRect[1], rx, ry, arcPtr->start,		arcPtr->extent)	    || HorizLineToArc(tRect[0], tRect[2], tRect[3], rx, ry,		arcPtr->start, arcPtr->extent)	    || VertLineToArc(tRect[0], tRect[1], tRect[3], rx, ry,		arcPtr->start, arcPtr->extent)	    || VertLineToArc(tRect[2], tRect[1], tRect[3], rx, ry,		arcPtr->start, arcPtr->extent)) {	return 0;    }    if ((width > 1.0) && !filled) {	rx -= width;	ry -= width;	if (HorizLineToArc(tRect[0], tRect[2], tRect[1], rx, ry, arcPtr->start,		    arcPtr->extent)		|| HorizLineToArc(tRect[0], tRect[2], tRect[3], rx, ry,		    arcPtr->start, arcPtr->extent)		|| VertLineToArc(tRect[0], tRect[1], tRect[3], rx, ry,		    arcPtr->start, arcPtr->extent)		|| VertLineToArc(tRect[2], tRect[1], tRect[3], rx, ry,		    arcPtr->start, arcPtr->extent)) {	    return 0;	}    }    /*     * The arc still appears to be totally disjoint from the rectangle,     * but it's also possible that the rectangle is totally inside the arc.     * Do one last check, which is to check one point of the rectangle     * to see if it's inside the arc.  If it is, we've got overlap.  If     * it isn't, the arc's really outside the rectangle.     */    if (ArcToPoint(canvas, itemPtr, rectPtr) == 0.0) {	return 0;    }    return -1;}/* *-------------------------------------------------------------- * * ScaleArc -- * *	This procedure is invoked to rescale an arc item. * * Results: *	None. * * Side effects: *	The arc referred to by itemPtr is rescaled so that the *	following transformation is applied to all point *	coordinates: *		x' = originX + scaleX*(x-originX) *		y' = originY + scaleY*(y-originY) * *-------------------------------------------------------------- */static voidScaleArc(canvas, itemPtr, originX, originY, scaleX, scaleY)    Tk_Canvas canvas;			/* Canvas containing arc. */    Tk_Item *itemPtr;			/* Arc to be scaled. */    double originX, originY;		/* Origin about which to scale rect. */    double scaleX;			/* Amount to scale in X direction. */    double scaleY;			/* Amount to scale in Y direction. */{    ArcItem *arcPtr = (ArcItem *) itemPtr;    arcPtr->bbox[0] = originX + scaleX*(arcPtr->bbox[0] - originX);    arcPtr->bbox[1] = originY + scaleY*(arcPtr->bbox[1] - originY);    arcPtr->bbox[2] = originX + scaleX*(arcPtr->bbox[2] - originX);    arcPtr->bbox[3] = originY + scaleY*(arcPtr->bbox[3] - originY);    ComputeArcBbox(canvas, arcPtr);}/* *-------------------------------------------------------------- * * TranslateArc -- * *	This procedure is called to move an arc by a given amount. * * Results: *	None. * * Side effects: *	The position of the arc is offset by (xDelta, yDelta), and *	the bounding box is updated in the generic part of the item *	structure. * *-------------------------------------------------------------- */static voidTranslateArc(canvas, itemPtr, deltaX, deltaY)    Tk_Canvas canvas;			/* Canvas containing item. */    Tk_Item *itemPtr;			/* Item that is being moved. */    double deltaX, deltaY;		/* Amount by which item is to be					 * moved. */{    ArcItem *arcPtr = (ArcItem *) itemPtr;    arcPtr->bbox[0] += deltaX;    arcPtr->bbox[1] += deltaY;    arcPtr->bbox[2] += deltaX;    arcPtr->bbox[3] += deltaY;    ComputeArcBbox(canvas, arcPtr);}/* *-------------------------------------------------------------- * * ComputeArcOutline -- * *	This procedure creates a polygon describing everything in *	the outline for an arc except what's in the curved part. *	For a "pie slice" arc this is a V-shaped chunk, and for *	a "chord" arc this is a linear chunk (with cutaway corners). *	For "arc" arcs, this stuff isn't relevant. * * Results: *	None. * * Side effects: *	The information at arcPtr->outlinePtr gets modified, and *	storage for arcPtr->outlinePtr may be allocated or freed. * *-------------------------------------------------------------- */static voidComputeArcOutline(arcPtr)    ArcItem *arcPtr;			/* Information about arc. */{    double sin1, cos1, sin2, cos2, angle, halfWidth;    double boxWidth, boxHeight;    double vertex[2], corner1[2], corner2[2];    double *outlinePtr;    /*     * Make sure that the outlinePtr array is large enough to hold     * either a chord or pie-slice outline.     */    if (arcPtr->numOutlinePoints == 0) {	arcPtr->outlinePtr = (double *) ckalloc((unsigned)		(26 * sizeof(double)));	arcPtr->numOutlinePoints = 22;    }    outlinePtr = arcPtr->outlinePtr;    /*     * First compute the two points that lie at the centers of     * the ends of the curved arc segment, which are marked with     * X's in the figure below:     *     *     *				  * * *     *			      *          *     *			   *      * *      *     *			 *    *         *    *     *			*   *             *   *     *			 X *               * X     *     * The code is tricky because the arc can be ovular in shape.     * It computes the position for a unit circle, and then     * scales to fit the shape of the arc's bounding box.     *     * Also, watch out because angles go counter-clockwise like you     * might expect, but the y-coordinate system is inverted.  To     * handle this, just negate the angles in all the computations.     */    boxWidth = arcPtr->bbox[2] - arcPtr->bbox[0];    boxHeight = arcPtr->bbox[3] - arcPtr->bbox[1];    angle = -arcPtr->start*PI/180.0;    sin1 = sin(angle);    cos1 = cos(angle);    angle -= arcPtr->extent*PI/180.0;    sin2 = sin(angle);    cos2 = cos(angle);    vertex[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;    vertex[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;    arcPtr->center1[0] = vertex[0] + cos1*boxWidth/2.0;    arcPtr->center1[1] = vertex[1] + sin1*boxHeight/2.0;    arcPtr->center2[0] = vertex[0] + cos2*boxWidth/2.0;    arcPtr->center2[1] = vertex[1] + sin2*boxHeight/2.0;    /*     * Next compute the "outermost corners" of the arc, which are     * marked with X's in the figure below:     *     *				  * * *     *			      *          *     *			   *      * *      *     *			 *    *         *    *     *			X   *             *   X     *			   *               *     *     * The code below is tricky because it has to handle eccentricity     * in the shape of the oval.  The key in the code below is to     * realize that the slope of the line from arcPtr->center1 to corner1     * is (boxWidth*sin1)/(boxHeight*cos1), and similarly for arcPtr->center2     * and corner2.  These formulas can be computed from the formula for     * the oval.     */    halfWidth = arcPtr->width/2.0;    if (((boxWidth*sin1) == 0.0) && ((boxHeight*cos1) == 0.0)) {	angle = 0.0;    } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -