Ongelma polaarikoordinaattitoteutuksen kanssa.

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by esa94 »

Ongelman kuvaus: X ja Y eivät ole lähelläkään sitä paikkaa, missä polaarikoordinaatit luulevat niiden ovan.
Ongelman laajuus: Liian iso
Mahd. syitä: -
Ongelman havainnoillistaminen: Aja alemman listauksen koodi

Funktiot:

Code: Select all

///////////////////////////////
//Polaarikoordinaattifunktiot//
//     FVD-YHTEENSOPIVA!     //
///////////////////////////////

//Polaarikoordinaattijärjestelmän avulla on helpompi esittää
//ympyröihin liittyviä... Juttuja. Koordinaatisto nimittäin
//ei olekaan enää X ja Y, vaan R ja T (Säde ja kiertokulma).
//Esimerkiksi samalla R:n arvolla, mutta eri T:n arvolla voidaan
//piirtää kaari.

//Nimi: Polar2X
//Kuvaus: Muuttaa polaarikoordinaatin tavalliseksi x-koordinaatiksi
//Parametrit: Integer _r, Integer _t
//  _r | Etäisyys keskipisteestä (vastaava, kuin ympyrän säde)
//  _t | Keskuskulma

Function Polar2X( _r#, _t# )

    Return _r * Cos( _t )

EndFunction 

//Nimi: Polar2Y
//Kuvaus: Muuttaa polaarikoordinaatin tavalliseksi y-koordinaatiksi
//Parametrit: Integer _r, Integer _t
//  _r | Etäisyys keskipisteestä (vastaava, kuin ympyrän säde)
//  _t | Keskuskulma

Function Polar2Y( _r#, _t# )

    Return _r * Sin( _t )

EndFunction 

//Nimi: XY2PolarR
//Kuvaus: Muuttaa XY-koordinaatit polaarikoordinaattein säteeksi (_r)
//Parametrit: Integer _x, Integer _y
//  _x
//  _y

Function XY2PolarR( _x#, _y# )

    Return Sqrt( ( _y^2 ) + ( _x^2 ) )

EndFunction

//Nimi: XY2PolarT
//Kuvaus: Muuttaa XY-koordinaatit polaarikoordinaattein kulmaksi (_t)
//Parametrit: Integer _x, Integer _y
//  _x
//  _y

Function XY2PolarT( _x#, _y# )

    If _x > 0 And _y >= 0 Then
    
        Return ATan( WrapAngle( _y / _x ) )
        
    ElseIf _x > 0 And _y < 0 Then
    
        Return WrapAngle( ATan( WrapAngle( _y / _x ) ) + 360 )
    
    ElseIf _x < 0 Then
    
        Return WrapAngle( ATan( WrapAngle( _y / _x ) ) + 180 )
    
    ElseIf _x = 0 And _y > 0 Then
    
        Return 90
    
    ElseIf _x = 0 And _y < 0 Then
    
        Return 270
        
    Else
        
        MakeError( "Polar coordinate failure. This shouldn't be possible!" )
        
    EndIf

EndFunction 
Testikoodi:

Code: Select all

SCREEN 480, 480

Include "polar.cb"

Repeat

x# = Rnd( 0, 360 )
y# = Rnd( 0, 360 )

px# = Polar2X( XY2PolarR( x, y ), XY2PolarT( x, y ) )
py# = Polar2Y( XY2PolarR( x, y ), XY2PolarT( x, y ) )

r = XY2PolarR( px, py )

ClearText
Color cbWhite
AddText "Original: ("+x+", "+y+") New: ("+px+", "+py+")"

Color cbRed
Line 240, 240, px / 2 + 240, py / 2 + 240
Circle 240 - ( r / 2 ), 240 - ( r / 2 ), r, 0

Color cbBlue
Line 240, 240, x / 2 + 80, y / 2 + 240

DrawScreen
WaitMouse
Forever
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Re: Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by Aavesoturi »

Testaamaan en pääse, mutta aika usein trigonometrian kanssa leikkiessä unohtuu, että tietokoneen näytöllä y-akseli kasvaa alaspäin, kun normaalissa koordinaatistossa se kasvaa ylöspäin. Tämän takia yleensä korjataan ottamalla Sin-tekijä mukaan negatiivisena ("miinus sin").
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by esa94 »

Aavesoturi wrote:Testaamaan en pääse, mutta aika usein trigonometrian kanssa leikkiessä unohtuu, että tietokoneen näytöllä y-akseli kasvaa alaspäin, kun normaalissa koordinaatistossa se kasvaa ylöspäin. Tämän takia yleensä korjataan ottamalla Sin-tekijä mukaan negatiivisena ("miinus sin").
!

Testaan!
EDIT:

Tutkin ongelmaa tarkemmin, ja nyt näyttää siltä, että kun x:n ja y:n etumerkit ovat vastakkaiset, ohjelma ei osaa laskea oikeaa kulmaa. Sen sijaan piste lukittuu y-akselille ja liikkuu vain pystysuunnassa. X = 0 ja y = 0 toimivat kuitenkin, siis niin kauan, kuin jompi kumpi on 0.

Ongelman aiheuttava funktio näyttäisi olevan ATan. Kun trigonometriaan en ole aivan järjettömästi perehtynyt, (Koodi tehty wikipedian perusteella) pitäisikö minun esim. kääntää etumerkki y:stä kulmaa laskettaessa?

Tuorein koodi:

Code: Select all

///////////////////////////////
//Polaarikoordinaattifunktiot//
//     FVD-YHTEENSOPIVA!     //
///////////////////////////////

//Polaarikoordinaattijärjestelmän avulla on helpompi esittää
//ympyröihin liittyviä... Juttuja. Koordinaatisto nimittäin
//ei olekaan enää X ja Y, vaan R ja T (Säde ja kiertokulma).
//Esimerkiksi samalla R:n arvolla, mutta eri T:n arvolla voidaan
//piirtää kaari.

//Nimi: Polar2X
//Kuvaus: Muuttaa polaarikoordinaatin tavalliseksi x-koordinaatiksi
//Parametrit: Integer _r, Integer _t
//  _r | Etäisyys keskipisteestä (vastaava, kuin ympyrän säde)
//  _t | Keskuskulma

Function Polar2X( _r#, _t# )

    Return _r * Cos( _t )

EndFunction 

//Nimi: Polar2Y
//Kuvaus: Muuttaa polaarikoordinaatin tavalliseksi y-koordinaatiksi
//Parametrit: Integer _r, Integer _t
//  _r | Etäisyys keskipisteestä (vastaava, kuin ympyrän säde)
//  _t | Keskuskulma

Function Polar2Y( _r#, _t# )

    Return -( _r * -Sin( _t ) )

EndFunction 

//Nimi: XY2PolarR
//Kuvaus: Muuttaa XY-koordinaatit polaarikoordinaattein säteeksi (_r)
//Parametrit: Integer _x, Integer _y
//  _x
//  _y

Function XY2PolarR( _x#, _y# )

    Return Sqrt( ( _y^2 ) + ( _x^2 ) )

EndFunction

//Nimi: XY2PolarT
//Kuvaus: Muuttaa XY-koordinaatit polaarikoordinaattein kulmaksi (_t)
//Parametrit: Integer _x, Integer _y
//  _x
//  _y

Function XY2PolarT( _x#, _y# )

    If _x > 0 And _y >= 0 Then
    
        Return ATan( WrapAngle( _y / _x ) )
        
    ElseIf _x > 0 And _y < 0 Then
    
        Return WrapAngle( ATan( WrapAngle( _y / _x ) ) + 360 )
    
    ElseIf _x < 0 Then
    
        Return WrapAngle( ATan( WrapAngle( _y / _x ) ) + 180 )
    
    ElseIf _x = 0 And _y > 0 Then
    
        Return 90
    
    ElseIf _x = 0 And _y < 0 Then
    
        Return 270
        
    ElseIf _x = 0 And _y = 0 Then

		Return 0

	Else
        
        MakeError( "Polar coordinate failure. This shouldn't be possible!" )
        
    EndIf

EndFunction 
Ja uusi testikoodi:

Code: Select all

SCREEN 480, 480

Include "polar.cb"

x# = 0
y# = 0

r# = 0
t# = 0

Repeat

r# = XY2PolarR( x, y )
t# = XY2PolarT( x, y )

px# = Polar2X( r, t )
py# = Polar2Y( r, t )

ClearText
Color cbWhite
AddText "Original: (x"+x+", y"+y+") From polar: (x"+px+", y"+py+")"
AddText "Polar coords: (r"+r+", t"+t+")"

If UpKey() Then y - 1
If DownKey() Then y + 1

If RightKey() Then x + 1
If LeftKey() Then x - 1

Color cbBlue
Dot 240 + x - 10, 240 + y
Dot 240 + x, 240 + y - 10
Dot 240 + x, 240 + y
Dot 240 + x, 240 + y + 10
Dot 240 + x + 10, 240 + y

Color cbRed
Dot 240 + px - 10, 240 + py
Dot 240 + px, 240 + py - 10
Dot 240 + px, 240 + py
Dot 240 + px, 240 + py + 10
Dot 240 + px + 10, 240 + py

DrawScreen
Forever
[/edit]
m1c
Member
Posts: 65
Joined: Tue Aug 28, 2007 5:10 pm
Location: \o

Re: Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by m1c »

Mikäli tarkoituksena on saada viivat piirtymään päällekkäin, vilkaise niiden piirtokoodeja. Sinisen viivan x-koordinaattiin lisätään 240 sijaan 80. Lisäksi parannusehdotus: käytä kulman ja pituuden laskemiseen GetAnglea ja Distancea. CB:n tapauksessa ne ovat nopeampia kuin perinteinen matematiikka, sillä ne vievät oletettavasti tavukoodissa huomattavasti vähemmän komentoja. Lisäksi atan on helvetistä.
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by esa94 »

m1c wrote:Mikäli tarkoituksena on saada viivat piirtymään päällekkäin, vilkaise niiden piirtokoodeja. Sinisen viivan x-koordinaattiin lisätään 240 sijaan 80. Lisäksi parannusehdotus: käytä kulman ja pituuden laskemiseen GetAnglea ja Distancea. CB:n tapauksessa ne ovat nopeampia kuin perinteinen matematiikka, sillä ne vievät oletettavasti tavukoodissa huomattavasti vähemmän komentoja. Lisäksi atan on helvetistä.
Kuten mainitsin, koodi on tehty suoraan kaavojen perusteella wikipediasta. Lisäksi edellisessä viestissäni on tuoreempi koodi, joka toimii paremmin... :)
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Re: Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by JATothrim »

Problem Solved. (? <- jos en tajunnut kysymystä oikein) Olit tunkenu WrapAnglea aivan väärään paikkaan ja turhaan. ja eh.. GetAngle() toimisi (väh. 50%) paremmin kuin tuo oma kulmakoodisi. Vikahan olis siinä että ATAN() parametri "_x / _y" Wrapattiin välille 0.0-360.0 eli _x tai _y :n negatiivisuus ei vaikuttanut mitenkään kulmaan, minkä vuoksi kulma "peilautui" Lähes samoin käy myös Abs(_x / _y) kanssa. Tossa molemmat koodit:

Code: Select all

///////////////////////////////
//Polaarikoordinaattifunktiot//
//     FVD-YHTEENSOPIVA!     //
///////////////////////////////

//Polaarikoordinaattijärjestelmän avulla on helpompi esittää
//ympyröihin liittyviä... Juttuja. Koordinaatisto nimittäin
//ei olekaan enää X ja Y, vaan R ja T (Säde ja kiertokulma).
//Esimerkiksi samalla R:n arvolla, mutta eri T:n arvolla voidaan
//piirtää kaari.

//Nimi: Polar2X
//Kuvaus: Muuttaa polaarikoordinaatin tavalliseksi x-koordinaatiksi
//Parametrit: Integer _r, Integer _t
//  _r | Etäisyys keskipisteestä (vastaava, kuin ympyrän säde)
//  _t | Keskuskulma

Function Polar2X( _r#, _t# )

    Return _r * Cos( _t )

EndFunction 

//Nimi: Polar2Y
//Kuvaus: Muuttaa polaarikoordinaatin tavalliseksi y-koordinaatiksi
//Parametrit: Integer _r, Integer _t
//  _r | Etäisyys keskipisteestä (vastaava, kuin ympyrän säde)
//  _t | Keskuskulma

Function Polar2Y( _r#, _t# )

    Return -( _r * -Sin( _t ) )

EndFunction 

//Nimi: XY2PolarR
//Kuvaus: Muuttaa XY-koordinaatit polaarikoordinaattein säteeksi (_r)
//Parametrit: Integer _x, Integer _y
//  _x
//  _y

Function XY2PolarR( _x#, _y# )

    'Return Sqrt( ( _y^2 ) + ( _x^2 ) )
	Return Distance(0,0,_x, _y)
EndFunction

//Nimi: XY2PolarT
//Kuvaus: Muuttaa XY-koordinaatit polaarikoordinaattein kulmaksi (_t)
//Parametrit: Integer _x, Integer _y
//  _x
//  _y

Function XY2PolarT( _x#, _y# )

    If _x > 0 And _y >= 0 Then
    
        Return ATan( _y / _x )
        
    ElseIf _x > 0 And _y < 0 Then
    
        Return WrapAngle( ATan(  _y / _x ) + 360 )
    
    ElseIf _x < 0 Then
    
        Return WrapAngle( ATan( _y / _x  ) + 180 )
    
    ElseIf _x = 0 And _y > 0 Then
    
        Return 90
    
    ElseIf _x = 0 And _y < 0 Then
    
        Return 270
        
    ElseIf _x = 0 And _y = 0 Then

      Return 0

   Else
        
        MakeError( "Polar coordinate failure. This shouldn't be possible!" )
        
    EndIf
	//^^^^ TAI:
	'Return GetAngle(0,0,_x,_y)
EndFunction 

SCREEN 480, 480

x# = 0
y# = 0

r# = 0
t# = 0

Repeat

r# = XY2PolarR( x, y )
t# = XY2PolarT( x, y )

px# = Polar2X( r, t )
py# = Polar2Y( r, t )

ClearText
Color cbWhite
AddText "Original: (x"+x+", y"+y+") From polar: (x"+px+", y"+py+")"
AddText "Polar coords: (r"+r+", t"+t+")"

If UpKey() Then y - 1
If DownKey() Then y + 1

If RightKey() Then x + 1
If LeftKey() Then x - 1

Color cbBlue
Dot 240 + x - 10, 240 + y
Dot 240 + x, 240 + y - 10
Dot 240 + x, 240 + y
Dot 240 + x, 240 + y + 10
Dot 240 + x + 10, 240 + y

Color cbRed
Dot 240 + px - 10, 240 + py
Dot 240 + px, 240 + py - 10
Dot 240 + px, 240 + py
Dot 240 + px, 240 + py + 10
Dot 240 + px + 10, 240 + py

DrawScreen
Forever
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by esa94 »

JATothrim wrote:GetAngle() toimisi (väh. 50%) paremmin kuin tuo oma kulmakoodisi.
En käytä niin paljon CB:tä saati sitten kulmia, että olisin ko. funktiota edes muistanut. Sitäpaitsi, kuten nyt tässä toitotan, kaikk isitä WrapAnglea lukuunottamatta oli pöltsitty suoraan Wikepediasta. :P
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Re: Ongelma polaarikoordinaattitoteutuksen kanssa.

Post by JATothrim »

Heh. (offtopikkia?) Itse yritin saada wikipediasta kopisittuna Shunting-Yard algotrimin, eikä se toimi kunnolla vieläkään. Puhumattakaan vektoreihin perustuvasta tömäyksen tunnistuksesta. :mrgreen: Ikävää kun "valmista" algotrimia pitää räknätä uudestaan eri kielellä, että se toimisi. Esimerkkinä voinen mainita minun tekemäni monimutkaisen tokenisaattorin, C++. (pilkkoo tekstiä sanoksi) yritin portata algotrimiä CoolBasicille, muuta CB:n merkkijonot toimivat aivan liian eri tavoin kuin STL:n string. Mm. "string.find_first_not_of()" puuttuu. :/ Tokenisaattoria varten pitäisi käytännössä tehdä uudet merkkijonot muistipaloilla.
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
Post Reply