Mercurial > sdl-ios-xcode
view src/libm/k_cos.c @ 3474:1edb86163d62
Of COURSE that trick wouldn't work on all renderers. Fall back to something for now, hopefully figure out a better way to do this later.
If we have to, we can use vertical line and horizontal line textures for vertical and horizontal lines, and then create custom textures for diagonal lines and software render those. It's terrible, but at least it would be pixel perfect.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 21 Nov 2009 07:22:59 +0000 |
parents | dc1eb82ffdaa |
children |
line wrap: on
line source
/* @(#)k_cos.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #if defined(LIBM_SCCS) && !defined(lint) static const char rcsid[] = "$NetBSD: k_cos.c,v 1.8 1995/05/10 20:46:22 jtc Exp $"; #endif /* * __kernel_cos( x, y ) * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 * Input x is assumed to be bounded by ~pi/4 in magnitude. * Input y is the tail of x. * * Algorithm * 1. Since cos(-x) = cos(x), we need only to consider positive x. * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. * 3. cos(x) is approximated by a polynomial of degree 14 on * [0,pi/4] * 4 14 * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x * where the remez error is * * | 2 4 6 8 10 12 14 | -58 * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 * | | * * 4 6 8 10 12 14 * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then * cos(x) = 1 - x*x/2 + r * since cos(x+y) ~ cos(x) - sin(x)*y * ~ cos(x) - x*y, * a correction term is necessary in cos(x) and hence * cos(x+y) = 1 - (x*x/2 - (r - x*y)) * For better accuracy when x > 0.3, let qx = |x|/4 with * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125. * Then * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)). * Note that 1-qx and (x*x/2-qx) is EXACT here, and the * magnitude of the latter is at least a quarter of x*x/2, * thus, reducing the rounding error in the subtraction. */ #include "math.h" #include "math_private.h" #ifdef __STDC__ static const double #else static double #endif one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ #ifdef __STDC__ double attribute_hidden __kernel_cos(double x, double y) #else double attribute_hidden __kernel_cos(x, y) double x, y; #endif { double a, hz, z, r, qx; int32_t ix; GET_HIGH_WORD(ix, x); ix &= 0x7fffffff; /* ix = |x|'s high word */ if (ix < 0x3e400000) { /* if x < 2**27 */ if (((int) x) == 0) return one; /* generate inexact */ } z = x * x; r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6))))); if (ix < 0x3FD33333) /* if |x| < 0.3 */ return one - (0.5 * z - (z * r - x * y)); else { if (ix > 0x3fe90000) { /* x > 0.78125 */ qx = 0.28125; } else { INSERT_WORDS(qx, ix - 0x00200000, 0); /* x/4 */ } hz = 0.5 * z - qx; a = one - qx; return a - (hz - (z * r - x * y)); } }