• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed niedokładność typu float?

0 głosów
76 wizyt
pytanie zadane 27 czerwca 2018 w C# i .NET przez DODO Bywalec (2,930 p.)
zamknięte 27 czerwca 2018 przez DODO

Witam.

Programuję sobie spokojnie spirograf(takie patyki co się kręcą, jeden przyczepiony do kolejnego i ostatni rysuje kreskę), odpalam, a tu takie dziwne cuś:

Jak widać, kolejne patyki nie są dokładnie przyczepione do poprzedników. latają w okolicy zakończeń poprzednich, ale niedokładnie. Kolejne patyki są coraz mniej dokładne. Warto dodać, że wartości przechowuję jako float'y. Czy to może być powodem problemów?

(używam Monogame i C#)

Główny kod:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;

namespace SPIROGRAF
{

    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        public Texture2D rect;

        List<Rod> allRods;
        
        Vector2 rod1Att = new Vector2(400, 300);

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        
        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 600;
            graphics.ApplyChanges();


            allRods = new List<Rod> { new Rod(100, 180, this), new Rod(80, 500, this), new Rod(90, 300, this), new Rod(100, 1000, this) }; //new Rod(100, 100, this)
            //allRods = new List<Rod> { new Rod(50, 10, this), new Rod(50, 20, this), new Rod(50, 30, this), new Rod(50, 40, this), new Rod(50, 50, this) }; //new Rod(100, 100, this)
            //allRods = new List<Rod> { };
            //for (int i = 0; i < 10; i++)
            //{
            //    allRods.Add(new Rod(50, i*10, this));
            //}
            base.Initialize();
        }
        
        protected override void LoadContent()
        {
            
            spriteBatch = new SpriteBatch(GraphicsDevice);

            rect = Content.Load<Texture2D>("rect"); // To biały kwadrat 1x1 px
        }
        
        protected override void UnloadContent()
        {
            
        }
        
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();
            

            for (int i = 0; i < allRods.Count; i++)
            {
                allRods[i].update(gameTime);

                if (i == 0)
                {
                    allRods[i].attachment = rod1Att;
                }
                else
                {
                    allRods[i].attachment = allRods[i - 1].end;
                }
            }

            

            base.Update(gameTime);
        }
        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();
            

            for (int i = 0; i < allRods.Count; i++)
            {
                allRods[i].draw(spriteBatch);
            }

            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

Klasa Rod:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;

namespace SPIROGRAF
{
    class Rod
    {
        public int length;
        public float degreesPerSeconds;

        public float degrees;
        public Vector2 attachment;
        public Vector2 end;

        Game1 g;

        public Rod(int l, int dps, Game1 game)
        {
            length = l;
            degreesPerSeconds = dps;
            g = game;
        }

        public void update(GameTime gameTime)
        {
            int fps = 60;
            try
            {
                fps = (int)(1 / gameTime.ElapsedGameTime.TotalSeconds);
            }
            catch (DivideByZeroException)
            {
                
            }
            
            degrees += degreesPerSeconds / fps;
            degrees = degrees % 360;
            float radians = MathHelper.ToRadians(degrees);
            end = Vector2.Transform(new Vector2(length, 0), Matrix.CreateRotationZ(radians)) + attachment; 
        }

        public void draw(SpriteBatch spriteBatch)
        {
            
            spriteBatch.Draw(g.rect, new Rectangle((int)attachment.X, (int)attachment.Y-1, length, 2), null, Color.CornflowerBlue, MathHelper.ToRadians(degrees), Vector2.Zero, SpriteEffects.None, 0);
            
        }
    }
}

Z góry dziękuję za przydatne odpowiedzi :)

komentarz zamknięcia: problem rozwiązany

1 odpowiedź

+1 głos
odpowiedź 27 czerwca 2018 przez DODO Bywalec (2,930 p.)

Dobra, sam rozwiązałem problem, więc zamykam, ale podzielę się rozwiązaniem coby przyszłe pokolenia nie miały takich problemów:

Obiekty klasy Rod pracowały na przestarzałych o jedną klatkę danych, a były rysowane na nowych, stąd niedokładności. Aby to naprawić, trzeba zamienić kolejność wywoływania funkcji update i przypisywania pozycji zaczepienia patyka.

Więc zamiast:

for (int i = 0; i < allRods.Count; i++)
            {
                allRods[i].update(gameTime);
 
                if (i == 0)
                {
                    allRods[i].attachment = rod1Att;
                }
                else
                {
                    allRods[i].attachment = allRods[i - 1].end;
                }
            }

powinno być:

for (int i = 0; i < allRods.Count; i++)
            {
                if (i == 0)
                {
                    allRods[i].attachment = rod1Att;
                }
                else
                {
                    allRods[i].attachment = allRods[i - 1].end;
                }

                allRods[i].update(gameTime);
            }

 

Podobne pytania

0 głosów
0 odpowiedzi 40 wizyt
0 głosów
2 odpowiedzi 83 wizyt
pytanie zadane 5 grudnia 2018 w Java przez kvbq Obywatel (1,300 p.)
0 głosów
1 odpowiedź 109 wizyt
pytanie zadane 13 marca 2016 w C i C++ przez milosz503 Początkujący (270 p.)
Porady nie od parady
Zadając pytanie postaraj się o szczegółowe opisanie problemu oraz udostępnienie wszystkich istotnych informacji (kody źródłowe, zrzuty ekranu itp.).Opisanie problemu

66,379 zapytań

113,130 odpowiedzi

239,488 komentarzy

46,637 pasjonatów

Przeglądających: 323
Pasjonatów: 7 Gości: 316

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...