Jump to content

  • Log In with Google      Sign In   
  • Create Account


Progressive Sin Wave


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 jack872   Members   -  Reputation: 149

Like
0Likes
Like

Posted 17 August 2013 - 05:06 AM

Hello there,

I'm trying to implement the water effect using the gamedev article about Hooke springs (http://gamedev.tutsplus.com/tutorials/implementation/make-a-splash-with-2d-water-effects/), but I wanted to add a sine wave generator to keep the waves moving. So I started writing a test code for generating a progressive sine wave:

Water::Water(uint32 uiPoints)
{
    m_points.resize(uiPoints);

    for (size_t i = 0; i < uiPoints; ++i)
	{
		m_points[i].p[0]		= (i+1.f) / uiPoints * WIDTH;
		m_points[i].p[1]		= 0.f;
		m_points[i].speed[1]	= 0.f;
	}

	TimerSystem::getInstance().addTickable(this);
}

void Water::tick(uint32 dt)
{
	m_uiDt += dt;

	// T = 2PI/w = 2PI*f 
	uint32 T = static_cast<uint32>(Math::TWO_PI/w_constant*1000.f); // (in ms)

	if (m_uiDt >= T)
		m_uiDt -= T;

	// Y(x, t) = A*sin(k*x - w*t)

	float t = m_uiDt / 1000.f;

	for (size_t i = 0; i < m_points.size(); ++i)
		m_points[i].p[1] = amplitude * std::sinf(k_constant*m_points[i].p[0] - w_constant*t);
}

void Water::render()
{
	// translate
	Math::Vector2f pos(0.f, Y_OFFSET);
	for (size_t i = 0; i < m_points.size(); ++i)
		Graphics::Renderer::getInstance().drawFillCircle(pos+m_points[i].p, 2.f, Math::Colorf::RED);
}

As far as I remember the formula is this one (long time I do not open a math book) but I started to render the points and I noticed that it's like generating 2 different waves:

k6xn.png

 

I made the springs and the particles without any problem but I can't get the sine wave working (the easiest thing I know, so funny), what's wrong?

Thanks in advice. :)



Sponsor:

#2 Brother Bob   Moderators   -  Reputation: 7774

Like
2Likes
Like

Posted 17 August 2013 - 05:49 AM

Your sine wave probably has a too high frequency and when you sample at discrete points at too long intervals you get an aliasing effect. Your contant k_constant is probably way too high.

 

From what I understand from your code, m_points[i].[0] is the X-coordinate of the pixel you want the point to appear at. If that's the case, then the first thing to do is to normalize this parameter. If you divide it by WIDTH, which I assume is the width in pixels of your window, you'll get a parameter then spans from 0 to 1 along the full length of the window. If you then multiply by 2*pi, the parameter then spans from 0 to 2*pi over the full length of the window which corresponds to a full period.

 

Now that you have a parameter that spans one full period, you can easily tweak the frequency by multiplying again by the number of periods you want.

m_points[i].p[1] = amplitude * std::sinf(m_points[i].p[0]/WIDTH * 2*pi * periods);

Thus, if you want 5 periods across the screen, set period to 5.


Edited by Brother Bob, 17 August 2013 - 05:50 AM.


#3 jack872   Members   -  Reputation: 149

Like
0Likes
Like

Posted 17 August 2013 - 06:22 AM

Thank you very much, you were right. Also, the casting from float to int amplified the problem.

Now I've changed my constants and used a float dt instead of an integer and works pretty good. :) 






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS