[Java3D] Het grote PI probleem

Pagina: 1
Acties:

  • OxiMoron
  • Registratie: November 2001
  • Laatst online: 27-06 10:54
Ik zit met het volgende:

Ik ben bezig in Java3D

en nu ben ik de camera aan het draaien.

Dan moet ie op een gegeven moment Math.cos(rotatieY) uitreken..

rotatieY is op het moment dat het fout gaat: Pi/2 (in een double is dus: 1.570796326794897)
maar zoals de mensen met een beetje wiskundige kennis weten is dat Cos(Pi/2) 0 (nul) moet zijn.

Echt Java zegt dat het: -7.657137397853899E-16 is
En dit is GEEN 0 (nul)

Nu denk ik dus dat het met afronding te maken heeft.
Ik Delphi opgestart, daar ingetypt:

Showmessage(FloatToStr(Cos(Pi/2)));

en ja hoor.. ook een vage waarde, maar GEEN 0 !

heeft iemand enig idee hoe ik dit probleem op kan lossen / of er iets naukeuriger is dan een double in Java ???

Albert Einstein: A question that sometime drives me hazy: Am I or are the others crazy?


Verwijderd

Je kan bijvoorbeeld een heel kleine waarde nemen waartussen de gewenste waarde moet liggen, zeg epsilon.

dan wordt het

0-epsilon<berekende_waarde<0+epsilon
otw
-epsilon<berkende_waarde<epsilon

  • OxiMoron
  • Registratie: November 2001
  • Laatst online: 27-06 10:54
hmm

dat zou nog wel eens kunnen werken :)

Albert Einstein: A question that sometime drives me hazy: Am I or are the others crazy?


Verwijderd

Komt inderdaad door afrondingsfouten. En helaas maakt een computer die. Pi (net als Pi/2) is niet eindig uit te drukken, dus daar treden altijd afrondingsfouten bij op als je het numeriek gaat berekenen.
Het makkelijkst is om een tolerantiewaarde 'delta' in te bouwen, waarvoor 0-delta<=Cos(Pi/2)<=0+delta.

edit:
too slow :)

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Google en de Java API documentatie helpen wellicht :) .

Als je echt decimale berekeningen wilt hebben moet je overigens de BigDecimal van IBM hebben. De klasse in de standaard Java library gebruikt geen decimale berekeningen. Er zit echter geen cos, sin, tan functie in dus die zal je zelf moeten schrijven of via Google ergens vinden. Er zijn een hoop wiskundige libraries op het web en daar zit vast wel iets tussen... PI in BigDecimal is overigens ook weer een probleem apart. Wellicht dat die ook ergens te vinden is ;) . Anders kan je hem van een String aanmaken (en ergens zoeken naar de exacte waarde ter grote van een BigDecimal)

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Gebruik matrices voor rotaties ipv de 12 eulerangle rotatie formules. Het is even doorbijten, maar werkt veel handiger: je kunt transformaties en rotaties in 1 berekening uitvoeren per vertex, plus ben je van het geneuzel af met je nulvalue.

  • OxiMoron
  • Registratie: November 2001
  • Laatst online: 27-06 10:54
Pff laat maar..

java rond alles intern ook al af, en houd hier dan verder geen rekening mee :(


Men neme een kubus:

omhoog = Y, rechts = Z, en naar voren is Z

er zijn 2 rotaties mogenlijk:

rotY (rotatie om de Y as) en rotR (rotatie vanuit het 0 punt met de camera omhoog)
constante R = 2 (afstand)

sommetjes:
Q = cos(rotR)*R
Y = sin(rotR)*R
X = sin(rotY)*Q
Z = cos(rotY)*Q

verder moet ik de rotaties over de 2 andere assen hebben:
rotX=tan(Y/Z)
rotZ=tan(Y/X)

Nu is dus 1 van de problemen: als rotY = 0 dan moet rotX gelijk zijn naar rotR Als rotY 1/2*Pi = dan moet rotZ gelijk zijn aan rotR

maar door die domme interne afronding van java is dat dus nooit gelijk.

nu kan ik door een paar ifstatements af te vangen dit corrigeren, maar dit is nog maar het begin.
bij een rotY van 1/32*Pi dan kloppen de waarden ook al niet :(

kortom: Java kan mijn geavanceerde wiskunde gewoon niet aan.

:+

Albert Einstein: A question that sometime drives me hazy: Am I or are the others crazy?


Verwijderd

Je zou hem natuurlijk kunnen afronden zondat ie naar 0 convergeert met round, floor, of ceil ofzo.

Note: BigDecimal zit niet alleen in IBM api maar tevens ook in de SDK van Sun, te vinden in java.math

Greetz, daRoBBie.

Verwijderd

Wat ik dan wel weer raar vind, is dat een simpel Casio machientje die afrondingen wél goed maakt... :?

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
daRoBBie: Note: BigDecimal zit niet alleen in IBM api maar tevens ook in de SDK van Sun, te vinden in java.math
Dat is dus een hele andere implementatie. In de toekomst zal deze misschien worden opgenomen in Java ipv de huidige implementatie van Sun.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • OxiMoron
  • Registratie: November 2001
  • Laatst online: 27-06 10:54
Hehe het is idd nogal dom.

Maar ik heb het probleem al veel simpeler opgelost..

De camera heeft z'n eigen assenstelsel.. dus ik roteer hem eerst en plaats hem vervolgens 2 naar achteren. :D

Dus hij roteerd nu eerst in de juiste positie en vervolgens op de juiste afstand :)


Problem solved :)



Maar ik blijf erbij dat het dom is dat Java dat niet goed kan :/

Albert Einstein: A question that sometime drives me hazy: Am I or are the others crazy?


  • TheOneLLama
  • Registratie: Oktober 2000
  • Laatst online: 20-01-2022

TheOneLLama

A llama like no llama before

Op vrijdag 15 maart 2002 13:39 schreef OxiMoron het volgende:
Maar ik blijf erbij dat het dom is dat Java dat niet goed kan :/
Wat doet java dan niet goed? reken het zelf maar na, dan kom je ook op die uitkomst. Jij verteld JAVA namelijk niet met PI te werken maar met een waarde die er zo dicht mogelijk in de buurt ligt, en met die gebruikte waarde komt JAVA op die uitkomst. Ook jou rekenmachine doet dat, die rond de uitkomst alleen weer af naar een minder preciese waarde. converteer de double maar naar een single dan wordt ie als het goed is gewoon nul. Je wilt natuurlijk niet dat JAVA die afronding standaard al voor je gaat doen want dat kost performance in het geval als dat niet belangrijk is.

Opera OpenOffice.org Jabber Psi jabber://llama@mordax.com


  • windancer
  • Registratie: Maart 2000
  • Laatst online: 08-09 01:06
Ga je rekenen met de uitkomst van de cos, of wil je de uitkomst hiervan met iets gaan vergelijken ?

Als je er verder mee wilt rekenen kan dat gewoon, O(-16) is echt genoeg dicht bij 0.

Als je de uitkomst wilt vergelijken zul je dat toch moeten doen XKB het voorstelt. Kijk of het verschil tussen de twee getallen kleiner is dan een bepaalde vaste waarde, bv 1.0e-9. Hier ontkom je niet aan als je met floating point getallen werkt, niemand ontkomt hier aan.

Mijn advies : als je wilt blijven rekenen met floating point getallen zul je moeten accepteren dat je ze niet zomaar kunt vergelijken.

  • OxiMoron
  • Registratie: November 2001
  • Laatst online: 27-06 10:54
Het ging om een positie/rotatie van een camera in een viruele ruimte.

die kleine afwijking kan uiteindelijk fataal worden.

Albert Einstein: A question that sometime drives me hazy: Am I or are the others crazy?


  • windancer
  • Registratie: Maart 2000
  • Laatst online: 08-09 01:06
Op vrijdag 15 maart 2002 20:51 schreef OxiMoron het volgende:
Het ging om een positie/rotatie van een camera in een viruele ruimte.

die kleine afwijking kan uiteindelijk fataal worden.
Dan moet je zorgen dat die kleine afwijking zich niet propageert. Het is onzin om de schuld hiervan bij de programmeertaal te leggen. Als dit het geval is moet je je numerieke methode bekijken.

BTW, een getal in de ordegrootte van 10^(-16) is precies genoeg voor mij in mijn dagelijks leven als software ontwikkelaar. Dit terwijl ik software schrijf die moet zorgen dat machines met een preciese van enkele nanometers moet werken (dus 10^(-9))

  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 19-08 19:06
Op vrijdag 15 maart 2002 09:51 schreef daxx909 het volgende:
Wat ik dan wel weer raar vind, is dat een simpel Casio machientje die afrondingen wél goed maakt... :?
rekenmachines ronden automatisch af en denken slim te zijn door 0.000000000000000 weer te geven als 0

  • Lone Gunman
  • Registratie: Juni 1999
  • Niet online
waarom zou die afwijking een probleem kunnen gaan geven dan ? misschien maak je geen gebruik van world & objectspace ?

Experience has taught me that interest begets expectation, and expectation begets disappointment, so the key to avoiding disappointment is to avoid interest.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik zie het hele probleem ook niet (en het is al helemaal niet de schuld van java). Je moet met computer graphics gewoon niet met cumulatieve waarden rekenen, zoals bijvoorbeeld een matrix die je steeds verandert aan de hand van de rotatie per frame, want dan kun je er donder op zeggen dat het na een x aantal frames niet meer klopt (dan krijg je van die effecten als shearing enzo). Wat je in dit voorbeeld wel moet doen is gewoon elke keer een nieuwe matrix berekenen, en niet steeds uitgaan van de vorige. Dus stel je doet eerst een rotatie naar links van 3 graden en daarna een van 5 graden, dan moet je dus berekenen:

matrix (3 + 5)

en niet

matrix (3) * matrix (5)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1