Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 07 Mar 2002
Offline Last Active Yesterday, 09:37 PM

#5309251 Faster Sin and Cos

Posted by on 02 September 2016 - 07:35 PM

What are people doing (in particular in games) that makes the calls to sin and cos take a noticeable chunk of time?

Calculating object rotations/orientations.

Do people really do that? 3D rotations are easily encoded using unit-length quaternions, and 2D rotations using unit-length complex numbers. If you use those, you basically don't need any trigonometric functions for rotations/orientations, just multiply-adds. I thought that's what everyone would be doing.

#5309166 Faster Sin and Cos

Posted by on 02 September 2016 - 07:55 AM

I can see L. Spiro is doing a good job of getting fast approximations to sin and cos, but I wonder why this is an important problem. What are people doing (in particular in games) that makes the calls to sin and cos take a noticeable chunk of time?

It would be nice if the results were never larger than one (e.g., Sin(1.57083237171173f) gives me 1.00000011920929f). Can the coefficient optimization be constrained by that?


EDIT: This forum is too smart for its own good. I am making two unrelated comments and I am trying to post them in two separate posts, but the forum combines them. Annoying.

#5308809 Locking 2 turning objects - the inertia problem

Posted by on 31 August 2016 - 03:39 AM

Conservation of angular momentum dictates that the sum of angular momentums before and after the locking should be equal: https://en.wikipedia.org/wiki/Angular_momentum . That leads to the answer.

#5308290 C++ 2048 game - movement function issue

Posted by on 27 August 2016 - 06:50 PM

Well, I had a bit of time, so I wrote it.

#include <iostream>

void move_row(int *array, int step) {
  int write_i = 0;
  int previous = 0;

  for (int read_i = 0; read_i < 4; ++read_i) {
    int entry = array[step*read_i];
    if (entry == 0)
    if (entry == previous) {
      array[step*(write_i - 1)] *= 2;
      previous = 0;
    else {
      array[step*(write_i++)] = entry;
      previous = entry;
  for (; write_i < 4; ++write_i)
    array[step*write_i] = 0;

void print_row(int *a) {
  for (int i = 0; i < 4; ++i)
    std::cout << a[i] << ' ';
  std::cout << '\n';

int main() {
  int a[4] = {4, 1, 1, 0};

  move_row(&a[3], -1);

#5308224 C++ 2048 game - movement function issue

Posted by on 27 August 2016 - 10:20 AM

Skipping over the empty entries of an array is a common algorithm. There is a neat way to do it using a loop with two indices, where you read using one index and write using the other one.

int write_i = 0;
for (int read_i = 0; read_i < n; ++read_i) {
  if (array[read_i] != Empty)
    array[write_i++] = array[read_i];

for (; write_i < n; ++write_i)
  array[write_i] = Empty;

A small modification of that code will do what you need for 2048. Also, instead of writing the loop four times, try to parametrize it so the same piece of code can do all four directions.

If you have trouble with it, I can post some code. But give it a try yourself first.

#5307460 I have an Idea..........

Posted by on 23 August 2016 - 01:12 PM


#5306259 Alternatives for std::heap?

Posted by on 16 August 2016 - 05:54 PM

I am sure what ApochPiQ said is right. Also, if you learn how a priority queue is implemented, you'll realize that std::heap is basically std::vector with some different interface thrown on top. You could very well reproduce that in Delphi.

#5305979 Point around point rotation

Posted by on 15 August 2016 - 08:43 AM

As others have said, floating-point numbers have limited precision and your results are normal. It would have been nice if you had told us what numbers you were getting as part of your initial report.

If you stop thinking in angles and start thinking of the rotation as the primary object to think about, you can get around this problem. If you use complex numbers, like in my code, you can use i as your rotation of 90 degrees. If you are not comfortable with complex numbers, you can still store the cosine and the sine in an object and call that a rotation. Then (0, 1) is exactly the rotation you want.

#5305907 Point around point rotation

Posted by on 15 August 2016 - 02:54 AM

I don't see a problem in your code. Perhaps you can provide a few more lines of code to turn this into a complete program that we can run ourselves to see the problem. If you could do so without depending on external libraries, it would be much better.

Here's one idea to make the code a bit simpler: If you have a function that rotates around the origin, you can write
glm::vec2 rotate_around_center(glm::vec2 point, glm::vec2 center, GLfloat angle) {
  return rotate_around_origin(point - center, angle) + center;
Another suggestion is to remove the conversion to radians and use radians consistently throughout your code. There is no reason to keep around degrees anywhere. If you need to display an angle in degrees, make the conversion just before displaying it, but don't pollute the rest of the program with degrees.

A slightly different mathematical approach is using complex numbers to represent both points on the plane and rotations. The point (x,y) becomes the number x+i*y, and the rotation of an angle alpha becomes cos(alpha)+i*sin(alpha). Now applying a rotation around the origin is achieved by simply multiplying the complex numbers corresponding to the point and the rotation.

EDIT: Here's some sample code:
#include <iostream>
#include <complex>

typedef std::complex<float> Complex;

float const Tau = std::atan(1.0f) * 8.0f;
float const Degree = Tau / 360.0f;

Complex rotate_around_origin(Complex point, Complex rotation) {
  return point * rotation;

Complex rotate_around_center(Complex point, Complex center, Complex rotation) {
  return rotate_around_origin(point - center, rotation) + center;

Complex rotation_from_angle(float angle) {
  return Complex(std::cos(angle), std::sin(angle));

int main() {
  Complex p(2.0, 5.0);
  Complex center(1.0, 0.0);
  Complex rotation = rotation_from_angle(90.0f * Degree);
  Complex rotated_p = rotate_around_center(p, center, rotation);

  std::cout << rotated_p << '\n';

#5305691 Calculus Problem!

Posted by on 13 August 2016 - 10:35 PM

Does anyone know how to integrate this expression for x please?:
ln(ax^n + c)
a, n and c are of course constants, and bot a and c should be positive but n will tend to be negative.

Why are you trying to do that? Without context it's hard to know if using a numerical method would be acceptable, for instance.

#5305147 Fast Square Root For Distance Calculations?

Posted by on 10 August 2016 - 12:14 PM

You started with an instance of XY problem and now you have changed your question into something that I will call the XZ problem. How about you just tell us what it is you are trying to accomplish, what you have tried so far and how it has failed?

#5304404 Only 12 Enemies, And My Fps Drops To 30, Why Is That?

Posted by on 06 August 2016 - 02:22 PM

How many matrices are we talking about? Interpolating a few thousand 3x3 matrices per frame shouldn't be a problem at all. If you are doing a lot of interpolation, perhaps you should consider using quaternions to represent your rotations, because interpolating quaternions is really cheap, especially if you use nlerp.

#5304208 Only 12 Enemies, And My Fps Drops To 30, Why Is That?

Posted by on 05 August 2016 - 09:03 AM

The number one rule in optimization is that you need to measure the improvements. There are rules of thumb and some people that have done optimization for a long time might have some sense for what's likely to work and what isn't; but that's not a substitute for testing.

By now you could have tried it, tested it and posted here to tell us how well it worked.

#5304162 Quick Way To Invert Matrix

Posted by on 05 August 2016 - 05:13 AM

He use a determinant , who know what it is ?

I do. Think of a 3x3 square matrix as a linear mapping from a R^3 to R^3. Linear mappings have the feature that volumes are scaled by them. The determinant is the scale that the volumes are multiplied by.

And who can tell how to use it to compute inverse matrix?

The most obvious connection is Cramer's rule.

For advanced users: There are other ways in which the determinant is connected to the inverse. One I learned about recently is that the gradient of the determinant (as a function of n^2 variables) is the transpose of the inverse times the determinant squared, or something like that. It turns you can use that fact together with automatic differentiation to compute the inverse in a really whacky way.

#5303973 String To Char* :(

Posted by on 04 August 2016 - 07:38 AM

Alvaro my program by default uses char* without null terminator

Sure, but strcpy doesn't care what conventions you have in your head.

strcpy(p, str.c_str());