do_tris.c revision 533545b5
1/***************************************************************************** 2Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 3 4 All Rights Reserved 5 6Permission to use, copy, modify, and distribute this software and its 7documentation for any purpose and without fee is hereby granted, 8provided that the above copyright notice appear in all copies and that 9both that copyright notice and this permission notice appear in 10supporting documentation, and that the name of Digital not be 11used in advertising or publicity pertaining to distribution of the 12software without specific, written prior permission. 13 14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20SOFTWARE. 21 22******************************************************************************/ 23 24 25#undef POLYTRIANGLE_HACK /* don't use this code */ 26#ifdef POLYTRIANGLE_HACK 27#include <X11/Xlibint.h> 28#endif 29 30#include "x11perf.h" 31#include "bitmaps.h" 32#include <stdio.h> 33#include <math.h> 34 35#define NUM_POINTS 3 /* 3 points to a triangle */ 36static XPoint *points; 37static GC pgc; 38 39#ifndef PI 40#define PI 3.14159265357989 41#endif 42 43static double 44Area(XPoint p1, XPoint p2, XPoint p3) 45{ 46 return 47 (p1.x*p2.y - p1.x*p3.y + p2.x*p3.y - p2.x*p1.y + p3.x*p1.y - p3.x*p2.y)/2; 48} 49 50/* 51static double 52Distance(XPoint p1, XPoint p2) 53{ 54 return sqrt((float) ((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y))); 55} 56*/ 57 58int 59InitTriangles(XParms xp, Parms p, int64_t reps) 60{ 61 int i, j, numPoints; 62 int rows; 63 int x, y; 64 int size, iradius; 65 double phi, phiinc, radius, delta, phi2, area, aarea; 66 XPoint *curPoint; 67 68 pgc = xp->fggc; 69 70 size = p->special; 71 phi = 0.0; 72 delta = 2.0 * PI / ((double) NUM_POINTS); 73 if (xp->version == VERSION1_2) { 74 radius = ((double) size) * sqrt(3.0)/2.0; 75 phiinc = delta/10.0; 76 } else { 77 /* Version 1.2's radius computation was completely bogus, and resulted 78 in triangles with sides about 50% longer than advertised. However, 79 this inadvertently resulted in triangles with areas just a little bit 80 smaller than the triangle that covers size^2 pixels, which would 81 make the area directly comparable to 10x10 rectangles and 10x10 82 trapezoids. So here's the new computation so -triangleN has the same 83 area as -rectN. 84 */ 85 radius = ((double) size) * sqrt(sqrt(16.0/27.0)); 86 phiinc = 1.75*PI / ((double) p->objects); 87 } 88 iradius = (int) (radius + 0.5); 89 90 numPoints = (p->objects) * NUM_POINTS; 91 points = (XPoint *)malloc(numPoints * sizeof(XPoint)); 92 curPoint = points; 93 x = iradius; 94 y = iradius; 95 rows = 0; 96 aarea = 0.0; 97 98 for (i = 0; i != p->objects; i++) { 99 for (j = 0; j != NUM_POINTS; j++) { 100 phi2 = phi + ((double) j) * delta; 101 curPoint->x = (int) ((double)x + (radius * cos(phi2)) + 0.5); 102 curPoint->y = (int) ((double)y + (radius * sin(phi2)) + 0.5); 103 curPoint++; 104 } 105 area = Area(curPoint[-1], curPoint[-2], curPoint[-3]); 106 aarea += area; 107/* printf("%6.1lf %6.1lf %6.1lf %6.1lf\n", 108 Distance(curPoint[-1], curPoint[-2]), 109 Distance(curPoint[-1], curPoint[-3]), 110 Distance(curPoint[-2], curPoint[-3]), 111 area); 112*/ 113 phi += phiinc; 114 y += 2 * iradius; 115 rows++; 116 if (y + iradius > HEIGHT || rows == MAXROWS) { 117 rows = 0; 118 y = iradius; 119 x += 2 * iradius; 120 if (x + iradius > WIDTH) { 121 x = iradius; 122 } 123 } 124 } 125/* printf("Average area = %6.2lf\n", aarea/p->objects); */ 126 127 SetFillStyle(xp, p); 128 129 return reps; 130} 131 132#ifndef POLYTRIANGLE_HACK 133 134void 135DoTriangles(XParms xp, Parms p, int64_t reps) 136{ 137 int i, j; 138 XPoint *curPoint; 139 140 for (i = 0; i != reps; i++) { 141 curPoint = points; 142 for (j = 0; j != p->objects; j++) { 143 XFillPolygon(xp->d, xp->w, pgc, curPoint, NUM_POINTS, Convex, 144 CoordModeOrigin); 145 curPoint += NUM_POINTS; 146 } 147 if (pgc == xp->bggc) 148 pgc = xp->fggc; 149 else 150 pgc = xp->bggc; 151 CheckAbort (); 152 } 153} 154 155#else 156 157static xReq _dummy_request = { 158 0, 0, 0 159}; 160 161static void 162XPolyTriangle(register Display *dpy, 163 Drawable d, GC gc, XPoint *points, 164 int n_triangles, int shape, int mode) 165{ 166 register xFillPolyReq *req; 167 register long nbytes; 168 int max_triangles; 169 int n_this_time; 170 int *buf, *pts; 171 int gcid; 172 int last; 173 174 max_triangles = (dpy->bufmax - dpy->buffer) / 28; 175 LockDisplay(dpy); 176 FlushGC(dpy, gc); 177 dpy->request += n_triangles; 178 pts = (int *) points; 179 gcid = gc->gid; 180 last = shape | (mode << 8); 181 while (n_triangles) 182 { 183 if ((n_this_time = max_triangles) > n_triangles) 184 n_this_time = n_triangles; 185 n_triangles -= n_this_time; 186 GetReqExtra(FillPoly, 187 (SIZEOF(xFillPolyReq) + 12) * n_this_time - SIZEOF(xFillPolyReq), req); 188 --dpy->request; 189 190 buf = req; 191 while (n_this_time--) 192 { 193 buf[0] = X_FillPoly | (7 << 16); 194 buf[1] = d; 195 buf[2] = gcid; 196 buf[3] = last; 197 buf[4] = pts[0]; 198 buf[5] = pts[1]; 199 buf[6] = pts[2]; 200 buf += 7; 201 pts += 3; 202 } 203 } 204 dpy->last_req = &_dummy_request; 205 UnlockDisplay(dpy); 206 SyncHandle(); 207} 208 209void 210DoTriangles(XParms xp, Parms p, int64_t reps) 211{ 212 int i, j; 213 XPoint *curPoint; 214 215 for (i = 0; i != reps; i++) { 216 XPolyTriangle (xp->d, xp->w, pgc, points, p->objects, Convex, 217 CoordModeOrigin); 218 if (pgc == xp->bggc) 219 pgc = xp->fggc; 220 else 221 pgc = xp->bggc; 222 CheckAbort (); 223 } 224} 225#endif 226 227void 228EndTriangles(XParms xp, Parms p) 229{ 230 free(points); 231} 232 233