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

📄 clip.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1986 Wayne A. Christopyher, U. C. Berkeley CAD GroupAuthor: 1982 Giles Billingsley**********//* * Some routines to do clipping of polygons, etc to boxes.  Most of this code * was rescued from MFB: *  sccsid "@(#)mfbclip.c   1.2  12/21/83" */#include "spice.h"#include "cpdefs.h"#include "ftedefs.h"#include "suffix.h"#define POLYGONBUFSIZE 512/* XXX */#define CODEMINX 1#define CODEMINY 2#define CODEMAXX 4#define CODEMAXY 8#define CODE(x,y,c)  c = 0;\                     if (x < l)\                         c = CODEMINX;\                     else if (x > r)\                         c = CODEMAXX;\                     if (y < b)\                         c |= CODEMINY;\                     else if (y > t)\                         c |= CODEMAXY;/* XXX */#define MAX(a, b) (((a) > (b)) ? (a) : (b))#define MIN(a, b) (((a) < (b)) ? (a) : (b))#define SWAPINT(a, b) { int xxxx = (a); (a) = (b); (b) = xxxx; }/* clip_line will clip a line to a rectangular area.  The returned * value is 'true' if the line is out of the AOI (therefore does not * need to be displayed) and 'false' if the line is in the AOI. */boolclip_line(pX1,pY1,pX2,pY2,l,b,r,t)    int *pX1, *pY1, *pX2, *pY2, l, b, r, t;{    int x1 = *pX1;    int y1 = *pY1;    int x2 = *pX2;    int y2 = *pY2;    int x,y,c,c1,c2;    CODE(x1,y1,c1)    CODE(x2,y2,c2)    while (c1 || c2) {        if (c1 & c2)            return (true); /* Line is invisible. */        if (!(c = c1))            c = c2;        if (c & CODEMINX) {            y = y1+(y2-y1)*(l-x1)/(x2-x1);            x = l;        } else if (c & CODEMAXX) {            y = y1+(y2-y1)*(r-x1)/(x2-x1);            x = r;        } else if (c & CODEMINY) {            x = x1+(x2-x1)*(b-y1)/(y2-y1);            y = b;        } else if (c & CODEMAXY) {            x = x1+(x2-x1)*(t-y1)/(y2-y1);            y = t;        }        if (c == c1) {            x1 = x;            y1 = y;            CODE(x,y,c1)        } else {            x2 = x;            y2 = y;             CODE(x,y,c2)        }    }    *pX1 = x1;    *pY1 = y1;    *pX2 = x2;    *pY2 = y2;    return (false); /* Line is at least partially visible.*/}/* This routine will clip a line to a circle, returning true if the line * is entirely outside the circle.  Note that we have to be careful not * to switch the points around, since in grid.c we need to know which is * the outer point for putting the label on. */boolclip_to_circle(x1, y1, x2, y2, cx, cy, rad)    int *x1, *y1, *x2, *y2,  cx, cy, rad;{    double perplen, a, b, c;    double tx, ty, dt;    double dtheta;    double theta1, theta2, tt, alpha, beta, gamma;    bool flip = false;    int i;    /* Get the angles between the origin and the endpoints. */    if ((*x1-cx) || (*y1-cy))	theta1 = atan2((double) *y1 - cy, (double) *x1 - cx);    else	theta1 = M_PI;    if ((*x2-cx) || (*y2-cy))	theta2 = atan2((double) *y2 - cy, (double) *x2 - cx);    else	theta2 = M_PI;    if (theta1 < 0.0)        theta1 = 2 * M_PI + theta1;    if (theta2 < 0.0)        theta2 = 2 * M_PI + theta2;    dtheta = theta2 - theta1;    if (dtheta > M_PI)        dtheta = dtheta - 2 * M_PI;    else if (dtheta < - M_PI)        dtheta = 2 * M_PI - dtheta;    /* Make sure that p1 is the first point */    if (dtheta < 0) {        tt = theta1;        theta1 = theta2;        theta2 = tt;        i = *x1;        *x1 = *x2;        *x2 = i;        i = *y1;        *y1 = *y2;        *y2 = i;        flip = true;        dtheta = -dtheta;    }    /* Figure out the distances between the points */    a = sqrt((double) ((*x1 - cx) * (*x1 - cx) + (*y1 - cy) * (*y1 - cy)));    b = sqrt((double) ((*x2 - cx) * (*x2 - cx) + (*y2 - cy) * (*y2 - cy)));    c = sqrt((double) ((*x1 - *x2) * (*x1 - *x2) +            (*y1 - *y2) * (*y1 - *y2)));    /* We have three cases now -- either the midpoint of the line is     * closest to the origon, or point 1 or point 2 is.  Actually the     * midpoint won't in general be the closest, but if a point besides     * one of the endpoints is closest, the midpoint will be closer than     * both endpoints.     */    tx = (*x1 + *x2) / 2;    ty = (*y1 + *y2) / 2;    dt = sqrt((double) ((tx - cx) * (tx - cx) + (ty - cy) * (ty - cy)));    if ((dt < a) && (dt < b)) {        /* This is wierd -- round-off errors I guess. */        tt = (a * a + c * c - b * b) / (2 * a * c);        if (tt > 1.0)            tt = 1.0;        else if (tt < -1.0)            tt = -1.0;        alpha = acos(tt);        perplen = a * sin(alpha);    } else if (a < b) {        perplen = a;    } else {        perplen = b;    }    /* Now we should see if the line is outside of the circle */    if (perplen >= rad)        return (true);    /* It's at least partially inside */    if (a > rad) {        tt = (a * a + c * c - b * b) / (2 * a * c);        if (tt > 1.0)            tt = 1.0;        else if (tt < -1.0)            tt = -1.0;        alpha = acos(tt);        gamma = asin(sin(alpha) * a / rad);        if (gamma < M_PI / 2)            gamma = M_PI - gamma;        beta = M_PI - alpha - gamma;        *x1 = cx + rad * cos(theta1 + beta);        *y1 = cy + rad * sin(theta1 + beta);    }    if (b > rad) {        tt = (c * c + b * b - a * a) / (2 * b * c);        if (tt > 1.0)            tt = 1.0;        else if (tt < -1.0)            tt = -1.0;        alpha = acos(tt);        gamma = asin(sin(alpha) * b / rad);        if (gamma < M_PI / 2)            gamma = M_PI - gamma;        beta = M_PI - alpha - gamma;        *x2 = cx + rad * cos(theta2 - beta);        *y2 = cy + rad * sin(theta2 - beta);    }    if (flip) {        i = *x1;        *x1 = *x2;        *x2 = i;        i = *y1;        *y1 = *y2;        *y2 = i;    }    return (false);}

⌨️ 快捷键说明

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