мое verbose_name
поля чужих ключей не напечатано в моих формах , т вращение обычные нарисованные спрайты работают отлично. Я думаю, что я близко, но я просто не знаю, что мне не хватает. Ниже приведены два моих метода «Draw_Sprite», один из которых просто рисует ранее загруженное растровое изображение на переданный холст. Другой, делает какое-то вращение лучше, чем я знаю, как повернуть спрайт на столько х градусов ... а затем нарисовать его , Если у меня есть хороший игровой цикл, который рисует несколько объектов, один тип будет повернутым. Тогда не повернутые спрайты мерцают, а вращающийся спрайт никогда не появляется. Хотя, если я сначала рисую не повернутые спрайты, все будет хорошо, но тогда Z-упорядоченность может быть испорчена (спрайты поверх элементов пользовательского интерфейса и т. Д.) ... Определения метода:
/*************************************************
* rotated sprite, ignore the whatever, its for ease of use and testing to have this argument list
* @param c canvas to draw on.
* @param whatever ignore
* @param rot degrees to rotate
* @return
*/
public int Draw_Sprite(Canvas c, int whatever, int rot) {
//rotating sprite
Rect src = new Rect(0, 0, width, height);
Rect dst = new Rect(x, y, x + width, y + height);
Matrix orig = c.getMatrix();
mMatrix = orig;
orig.setTranslate(0, 0);
orig.postRotate(rot, x+width/2, y+height/2);
c.setMatrix(orig);
c.drawBitmap(images[curr_frame], src, dst, null);
c.setMatrix(mMatrix); //set it back so all things afterwards are displayed correctly.
isScaled=false;
return 1;
}
/********************************************************
* draw a regular sprite to canvas c
* @param c
* @return
*/
public int Draw_Sprite(Canvas c) {
Rect src = new Rect(0, 0, width, height);
Rect dst = new Rect(x, y, x + width, y + height);
c.drawBitmap(images[curr_frame], src, dst, null);
isScaled=false;
return 1;
}
А теперь использование:
void onDraw(Canvas c)
{
canvas.drawRect( bgRect, bgPaint); //draw the background
//draw all game objects
// draw the normal items
for (GameEntity graphic : _graphics) {
graphic.toScreenCoords((int)player_x, (int)player_y);
if(graphic.getType().equals("planet")) //draw planets
graphic.Draw_Sprite(canvas); //before the rotation call draws fine
else
{
//rotate all space ships every frame so i see them spinning
//test rotation
mRot +=5;
if(mRot>=360)
mRot=0;
graphic.Draw_Sprite(canvas, 0, mRot); //yes function name will be better in future. this rotates spins draws fine
}
}
thePlayer.Draw_Sprite(canvas); //FLICKERS
drawUI(canvas);//all things here flickr
}
Так оно и есть, вещи после вызова ротационного розыгрыша отрисовываются правильно. Но проблема в том, что это мерцает. Есть ли простой способ узнать, сколько представимых действительных чисел находится между двумя в представлении IEEE-754 (или в любом представлении, используемом используемой машиной)?
Я не знаю, для чего вы будете это использовать, но если оба числа с плавающей запятой имеют одинаковую степень, это должно быть возможно. Поскольку экспонента хранится в старших битах, загрузка байтов с плавающей запятой (в данном случае 8 байтов) в виде целого числа и вычитание одного из другого должно дать желаемое число. Я использую структурную модель, чтобы упаковать числа с плавающей запятой в двоичное представление, а затем распаковать их как (C, 8 байт) long ints:
>>> import struct
>>> a = struct.pack("dd", 1.000000,1.000001)
>>> b = struct.unpack("ll",a)
>>> b[1] - b[0]
4503599627
>>> a = struct.pack("dd", 1.000000000,1.000000001)
>>> b = struct.unpack("ll",a)
>>> b[1] - b[0]
4503600
>>>
Для положительных чисел b > a > 0 ответ приблизительно:
(2**52) ** (log(b,2) - log(a,2))
Существует 52 бита мантиссы (после подразумеваемой 1), умноженной на 2 в экспоненту.
Таким образом, в диапазоне [1:2) содержится 2**52 числа, как и в диапазоне [1024:2048)
.Я бы посмотрел на функцию frexp в математическом модуле. В приведенном ниже примере извлекается мантисса и преобразуется в целое число. Разница должна быть количеством поплавков между двумя значениями.
>>> math.frexp(1.1234567890)[0] * 2**53
5059599576307254.0
>>> math.frexp(1.12345678901)[0] * 2**53
5059599576352290.0
Следующий код должен это сделать:
import math
import sys
def delta(x,y):
'''Return the number of floats between x and y.'''
x = float(x)
y = float(y)
if x == y:
return 0
elif x < y:
return -delta(y,x)
else:
x_mant, x_exp = math.frexp(x)
y_mant, y_exp = math.frexp(y)
x_int = int(x_mant * 2**(sys.float_info.mant_dig + x_exp - y_exp))
y_int = int(y_mant * 2**sys.float_info.mant_dig)
return x_int - y_int
print(delta(1.123456789, 1.1234567889999))
450
>>>
AFAIK, числа с плавающей запятой IEEE754 обладают интересным свойством. Если у вас есть float f, то
(*(int*)&f + 1)
при определенных условиях это следующее представимое число с плавающей запятой. Таким образом, для чисел с плавающей запятой a и b
*(int*)&a - *(int*)&b
даст вам количество чисел с плавающей запятой между этими числами.
См. http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm для получения дополнительной информации.