Re: [pygame] exact algebraic numbers?

2009-11-29 Thread Michael George

Michael George wrote:

Greg Ewing wrote:

But the back of my envelope is not wide enough
to accommodate any more of this.

A little bit further and you would have seen the fail: sqrt(3) * 
sqrt(6) = 3 * sqrt(2) and we're back where we started. However my 
algebra book assures me (non-constructively) that  {1, sqrt(2), 
sqrt(3), sqrt(6)} is a basis for the smallest field over the rationals 
containing sqrt(2) and sqrt(3), so it should be possible to divide.  I 
just have to chase the proofs backwards to figure out how.  I'll let 
you know.


In the end the solution came out rather nicely.  Here's my 
implementation (sans comparisons) for anyone who is interested.


--Mike
import fractions
from math import sqrt

FLOAT_SQRT2 = sqrt(2)
FLOAT_SQRT3 = sqrt(3)
FLOAT_SQRT6 = sqrt(6)

class Number(object):
	"""
	Represents a number of the form [a1 + a2*sqrt(2) + a3*sqrt(3) + a6*sqrt(6)]/d, where ai and d are integers
	"""

	__slots__ = ['a1', 'a2', 'a3', 'a6', 'd']

	def __init__(self, a1=0, a2=0, a3=0, a6=0, d=1):
		self.a1 = a1
		self.a2 = a2
		self.a3 = a3
		self.a6 = a6
		self.d  = d
		self.reduce()

	def __copy__(self):
		return Number(self.a1, self.a2, self.a3, self.a6, self.d)

	#
	# string conversions
	#

	def __repr__(self):
		return 'Number(%d,%d,%d,%d,%d)' % tuple(self)

	def __str__(self):
		return '[%d%+d*sqrt(2)%+d*sqrt(3)%+d*sqrt(6)]/%d' % tuple(self)

	def __unicode__(self):
		return u'[%d%+d\u221a2%+d\u221a3%+d\u221a6]/%d' % tuple(self)

	#
	# comparison operators
	#

	def __eq__(self, other):
		a1, a2, a3, a6, ad = self
		b1, b2, b3, b6, bd = other

		return ad*b1 == bd*a1 \
		   and ad*b2 == bd*a2 \
		   and ad*b3 == bd*a3 \
		   and ad*b6 == bd*a6

	def __neq__(self, other):
		return not self.__eq__(other)

	def __cmp__(self, other):
		# TODO
		return NotImplemented

	def __nonzero__(self):
		return self.a1 != 0 \
		or self.a2 != 0 \
		or self.a3 != 0 \
		or self.a6 != 0

	#
	# sequence operators
	#

	def __iter__(self):
		return iter((self.a1, self.a2, self.a3, self.a6, self.d))

	#
	# arithmetic operators
	#

	def __add__(self, other):
		a1, a2, a3, a6, ad = self
		b1, b2, b3, b6, bd = other

		return Number(bd*a1 + ad*b1,
		  bd*a2 + ad*b2,
		  bd*a3 + ad*b3,
		  bd*a6 + ad*b6,
		  ad*bd)

	def __sub__(self, other):
		return self + (-other)

	def __mul__(self, other):
		a1, a2, a3, a6, ad = self
		b1, b2, b3, b6, bd = other

		c1 =   a1*b1 + 2*a2*b2 + 3*a3*b3 + 6*a6*b6
		c2 =   a1*b2 +   a2*b1 + 3*a3*b6 + 3*a6*b3
		c3 =   a1*b3 + 2*a2*b6 +   a3*b1 + 2*a6*b2
		c6 =   a1*b6 +   a2*b3 +   a3*b2 +   a6*b1
		cd =   ad*bd

		return Number(c1, c2, c3, c6, cd)

	def __div__(self, other):
		return self * other.inv()

	def __radd__(self, other):
		return self + other

	def __rsub__(self, other):
		return (-self) + other

	def __rmul__(self, other):
		return self * other

	def __rdiv__(self, other):
		return self.inv() * other

	def __neg__(self):
		return Number(-self.a1, -self.a2, -self.a3, -self.a6, self.d)

	def __pos__(self):
		return self

	def __abs__(self):
		# TODO
		pass

	def __complex__(self):
		return complex(self.__float__())

	def __float__(self):
		return self.a1 + self.a2*FLOAT_SQRT2 + self.a3*FLOAT_SQRT3 + self.a6*FLOAT_SQRT6

	#
	# helper functions
	#

	def conj2(self):
		"""conjugate the sqrt(2) portion"""
		return Number(self.a1, -self.a2, self.a3, -self.a6, 1)

	def conj3(self):
		"""conjugate the sqrt(3) portion"""
		return Number(self.a1, self.a2, -self.a3, -self.a6, 1)

	def inv(self):
		factor1 = self.conj2()
		current = self * factor1
		assert current.a2 == current.a6 == 0

		factor2 = current.conj3()
		current = current * factor2 # = self * factor1 * factor2
		assert current.a2 == current.a3 == current.a6 == 0

		return Number(current.d, 0, 0, 0, current.a1) * factor1 * factor2

	def reduce(self):
		gcd = reduce(fractions.gcd, self)
		self.a1 = self.a1 / gcd
		self.a2 = self.a2 / gcd
		self.a3 = self.a3 / gcd
		self.a6 = self.a6 / gcd
		self.d  = self.d  / gcd

NMBR1 = Number(1,0,0,0,1)
SQRT2 = Number(0,1,0,0,1)
SQRT3 = Number(0,0,1,0,1)
SQRT6 = Number(0,0,0,1,1)



Re: [pygame] exact algebraic numbers?

2009-11-29 Thread Michael George

Greg Ewing wrote:

But the back of my envelope is not wide enough
to accommodate any more of this.

A little bit further and you would have seen the fail: sqrt(3) * sqrt(6) 
= 3 * sqrt(2) and we're back where we started. However my algebra book 
assures me (non-constructively) that  {1, sqrt(2), sqrt(3), sqrt(6)} is 
a basis for the smallest field over the rationals containing sqrt(2) and 
sqrt(3), so it should be possible to divide.  I just have to chase the 
proofs backwards to figure out how.  I'll let you know.

As for libraries dealing with this kind of stuff, there
might be something in Sage. But you're probably not going to
want to bolt Sage into your game...



Ah, I'd not seen sage, that looks cool.  I agree though, prolly don't 
want it as part of my game :).


--Mike


Re: [pygame] exact algebraic numbers?

2009-11-29 Thread Greg Ewing

Michael George wrote:
I'm trying to implement a game that allows dragging of 
objects while maintaining the fact that they do not intersect one 
another.  I want to be able to drag one object so that it abuts 
another.


Another way to approach this is to allow a tolerance when
deciding whether two objects abut. If the tolerance is less
than a pixel, the player won't be able to tell the difference.


a + b*sqrt(2) + c*sqrt(3) + d*sqrt(6).

These are closed under multiplication and addition, still not sure about 
division


Hmm. Possibly it might be, although the formulas are going
to get pretty horrendous. For example, a quick calculation
shows that

  1 / (a + b*sqrt(2)) = (a - b*sqrt(2)) / (a*a-2*b*b)

which you can get by multiplying top and bottom by
(a - b*sqrt(2)).

Attempting the first stage of a similar trick using the
full form, I got

(a + b*sqrt*(2) + c*sqrt(3) + d*sqrt(6)) * (a - b*sqrt(2))

= (a*a-2*b*b) + (a*c-2*b*d)*sqrt(3) + (a*d-b*c)*sqrt(6)

This no longer contains a sqrt(2) term, which is encouraging.
Presumably one could then go on to multiply this by
(a*a-2*b*b) - (a*c-2*b*d)*sqrt(3) to eliminate the
sqrt(3) term, and then E - F*sqrt(6) for some E and F to
be determined. But the back of my envelope is not wide enough
to accommodate any more of this.

As for libraries dealing with this kind of stuff, there
might be something in Sage. But you're probably not going to
want to bolt Sage into your game...

--
Greg


Re: [pygame] exact algebraic numbers?

2009-11-29 Thread rouiller olivier
Hi Mike,

Such algebraic numbers are used in computational geometry, you can take a
look at CGAL http://www.cgal.org, it's a powerfull Computational geometry
written in C++ (a python binding exists) and it has an algebraic kernel for
exact computation of points on a circle or on a sphere.
I'm not sure that it includes the transformations because it is done to
maintain data structures like meshes, etc...
Well you have to see if it suits your need and if the effort of installing
it is woth it!

Regards.
Olivier

2009/11/29 René Dudfield 

> On Sun, Nov 29, 2009 at 5:59 AM, Michael George 
> wrote:
> >
> > Hello,
> >
> > For my game I need to represent right isosceles triangles, and do
> operations including translation and rotation in 15 degree increments.
>  Unfortunately, I cannot tolerate rounding error, because it will cause bad
> visual and gameplay artifacts.  I'm thinking of representing points as
> vectors where the components are of the form
> >
> > a + b * sqrt(2) + c * sqrt(3) + d * sqrt(6)
> >
> > where a, b, c, and d are rationals.  I believe numbers of this form are
> sufficient for my purposes, although I haven't worked out all the proofs
> yet.  Anyway, I was wondering if anyone has done anything similar and can
> suggest a library I can use for manipulating such vectors before I go off
> and implement it myself.
> >
> > Thanks!
> >
> > --Mike
>
>
> hi,
>
> python 2.6 and 3.1 have a fractions module:
> http://docs.python.org/library/fractions.html
>
> The Fraction class inherits from the abstract base class numbers.Rational:
>http://docs.python.org/library/numbers.html#numbers.Rational
>
> To avoid rounding (and other numerical) errors, the typical technique
> is to apply the transformations each time from the identity matrix.
> So in a game where a rotation happens at say 1.0 - 1.444 degrees each
> frame, you keep count of the total rotation (eg 1.444) and apply the
> total rotation every frame.  Rather than applying the 1.0 rotation one
> frame, and then applying the 1.444 rotation the next frame.   Over
> 10,000 frames or so, you can see there would be little rounding error.
>
> You can also use integers instead of floats, but divide the value by
> 1,000,000 or so.  eg, 1.444 degrees could be 1,444,000.  Then as you
> do not get the floating point problems.  If all of your angles are
> between 0-360, and the angle increments are also small it turns out
> ok.  Python has a long type, so you can get a lot of precision this
> way, and avoid floating point problems somewhat.  Just before you use
> the rotation, you can divide the number by 1,000,000 or so(1444000 /
> 100 == 1.444).
>
>
> cu.
>



-- 
Rouiller Olivier
06 79 66 89 63
Résidence Léonard de Vinci
App. A008
59650 Villeneuve d'Ascq


Re: [pygame] exact algebraic numbers?

2009-11-29 Thread Michael George

DR0ID wrote:

Michael George schrieb:

Hello,

For my game I need to represent right isosceles triangles, and do 
operations including translation and rotation in 15 degree 
increments.  Unfortunately, I cannot tolerate rounding error, because 
it will cause bad visual and gameplay artifacts.  I'm thinking of 
representing points as vectors where the components are of the form


a + b * sqrt(2) + c * sqrt(3) + d * sqrt(6)

where a, b, c, and d are rationals.  I believe numbers of this form 
are sufficient for my purposes, although I haven't worked out all the 
proofs yet.  Anyway, I was wondering if anyone has done anything 
similar and can suggest a library I can use for manipulating such 
vectors before I go off and implement it myself.


Thanks!

--Mike


Hi

I don't think that you can avoid rounding errors, unless you use a 
math library that takes the math errors of the computer into account 
(which can differ from hardware to hardware).


I'm not sure, why you want to represent points in such a complicated 
way, but I don't know the theory about it and I'm not a mathematician.


One way to go is to accumulate the angle of a rotation (same for 
translation) and use the accumulated angle on a object to transform it 
into the right orientation (if you do use a previously rotated object 
then you will get much more rounding errors over time!). Using that 
way one would have a variable 'angle' which would be incremented in 15 
degree steps (15, 30, 45,...) and use it to construct the rotation 
matrix (or whatever it is used to rotate). This should be precise enough.


Unless you can draw using subpixels, you will have rounding errors 
when trying to draw the points on integer coordinates of the screen 
anyway.


Maybe I'm wrong.

~DR0ID


For the curious:

The reason I need exact arithmetic is not for drawing, but for collision 
response.  I'm trying to implement a game that allows dragging of 
objects while maintaining the fact that they do not intersect one 
another.  I want to be able to drag one object so that it abuts 
another.  So if a user surrounds one object with other objects, then 
drags the center object away, I want them to be able to "pop" it back 
into the hole.  If there's rounding errors, then it won't necessarily 
fit.  That's the easiest example, but I'm pretty sure there are others 
where things won't work right.


In this case, I'm dealing with very specific shapes, namely right 
triangles with legs of length 1.  Those can be represented with integer 
coordinates ((0, 0), (0,1), (1,0)).  However it turns out my snapping 
algorithm requires division, so I need rational numbers.  So far, so 
good.  But if you rotate a triangle by 45 degrees, you start needing to 
deal with sqrt(2) in the coordinates.  For example, ((0,0), (sqrt(2)/2, 
sqrt(2)/2), (-sqrt(2)/2)).  Luckily, numbers of the form a + b*sqrt(2) 
are good enough for this case, and you can still divide them exactly 
using integer arithmetic!  Similarly, you may recall from high school 
geometry (I had to look it up) that a cos 30 = sqrt(3)/2.  So if I allow 
rotation by 30 degrees, then I can represent those by a + b*sqrt(3).


But it turns out that composing rotations requires multiplication, so to 
get 15 degrees for example, you can rotate by 45 and then back by 30, 
and multiplying it out you get ((0,0), (sqrt(2) + sqrt(6), -sqrt(2) + 
sqrt(6))/4, [left for reader]).  So in general, you can represent all of 
the points on the unit circle in 15 degree increments using only integer 
arithmetic using the form


a + b*sqrt(2) + c*sqrt(3) + d*sqrt(6).

These are closed under multiplication and addition, still not sure about 
division (you might need quotients of these things in general, or 
worse).  I need to relearn my abstract algebra.



--Mike





Re: [pygame] exact algebraic numbers?

2009-11-29 Thread René Dudfield
On Sun, Nov 29, 2009 at 5:59 AM, Michael George  wrote:
>
> Hello,
>
> For my game I need to represent right isosceles triangles, and do operations 
> including translation and rotation in 15 degree increments.  Unfortunately, I 
> cannot tolerate rounding error, because it will cause bad visual and gameplay 
> artifacts.  I'm thinking of representing points as vectors where the 
> components are of the form
>
> a + b * sqrt(2) + c * sqrt(3) + d * sqrt(6)
>
> where a, b, c, and d are rationals.  I believe numbers of this form are 
> sufficient for my purposes, although I haven't worked out all the proofs yet. 
>  Anyway, I was wondering if anyone has done anything similar and can suggest 
> a library I can use for manipulating such vectors before I go off and 
> implement it myself.
>
> Thanks!
>
> --Mike


hi,

python 2.6 and 3.1 have a fractions module:
    http://docs.python.org/library/fractions.html

The Fraction class inherits from the abstract base class numbers.Rational:
http://docs.python.org/library/numbers.html#numbers.Rational

To avoid rounding (and other numerical) errors, the typical technique
is to apply the transformations each time from the identity matrix.
So in a game where a rotation happens at say 1.0 - 1.444 degrees each
frame, you keep count of the total rotation (eg 1.444) and apply the
total rotation every frame.  Rather than applying the 1.0 rotation one
frame, and then applying the 1.444 rotation the next frame.   Over
10,000 frames or so, you can see there would be little rounding error.

You can also use integers instead of floats, but divide the value by
1,000,000 or so.  eg, 1.444 degrees could be 1,444,000.  Then as you
do not get the floating point problems.  If all of your angles are
between 0-360, and the angle increments are also small it turns out
ok.  Python has a long type, so you can get a lot of precision this
way, and avoid floating point problems somewhat.  Just before you use
the rotation, you can divide the number by 1,000,000 or so(1444000 /
100 == 1.444).


cu.


Re: [pygame] exact algebraic numbers?

2009-11-29 Thread DR0ID

Michael George schrieb:

Hello,

For my game I need to represent right isosceles triangles, and do 
operations including translation and rotation in 15 degree 
increments.  Unfortunately, I cannot tolerate rounding error, because 
it will cause bad visual and gameplay artifacts.  I'm thinking of 
representing points as vectors where the components are of the form


a + b * sqrt(2) + c * sqrt(3) + d * sqrt(6)

where a, b, c, and d are rationals.  I believe numbers of this form 
are sufficient for my purposes, although I haven't worked out all the 
proofs yet.  Anyway, I was wondering if anyone has done anything 
similar and can suggest a library I can use for manipulating such 
vectors before I go off and implement it myself.


Thanks!

--Mike


Hi

I don't think that you can avoid rounding errors, unless you use a math 
library that takes the math errors of the computer into account (which 
can differ from hardware to hardware).


I'm not sure, why you want to represent points in such a complicated 
way, but I don't know the theory about it and I'm not a mathematician.


One way to go is to accumulate the angle of a rotation (same for 
translation) and use the accumulated angle on a object to transform it 
into the right orientation (if you do use a previously rotated object 
then you will get much more rounding errors over time!). Using that way 
one would have a variable 'angle' which would be incremented in 15 
degree steps (15, 30, 45,...) and use it to construct the rotation 
matrix (or whatever it is used to rotate). This should be precise enough.


Unless you can draw using subpixels, you will have rounding errors when 
trying to draw the points on integer coordinates of the screen anyway.


Maybe I'm wrong.

~DR0ID



[pygame] exact algebraic numbers?

2009-11-28 Thread Michael George

Hello,

For my game I need to represent right isosceles triangles, and do 
operations including translation and rotation in 15 degree increments.  
Unfortunately, I cannot tolerate rounding error, because it will cause 
bad visual and gameplay artifacts.  I'm thinking of representing points 
as vectors where the components are of the form


a + b * sqrt(2) + c * sqrt(3) + d * sqrt(6)

where a, b, c, and d are rationals.  I believe numbers of this form are 
sufficient for my purposes, although I haven't worked out all the proofs 
yet.  Anyway, I was wondering if anyone has done anything similar and 
can suggest a library I can use for manipulating such vectors before I 
go off and implement it myself.


Thanks!

--Mike