How to fix the delay caused by Mathf.Sin


I’m making a simple interactive mechanism of a reciprocating engine.
I am experiencing some weird behavior from Unity.

As the piston gets closer to top dead center and bottom dead center, it is in the right position in relationship to the lever arm. However, when the piston is moving between these positions, a gap develops, as if the crankshaft was lagging, and the piston was moving too fast.

alt text

Here’s the code that makes it all happen

    coursemod = Mathf.Sin ((shaft.transform.rotation.eulerAngles.y)*Mathf.PI/180f);
    course = (longrodscale * (25.4f) * coursemod) + longrodscale *25.4f;
    tempv = this.transform.position;
    tempz = course -5f;	
    tempv.z = tempz;
    this.transform.position = tempv;`


  • What I am doing is first getting the sine of the rotation angle of the shaft so I get values between -1 and 1 which are assigned to “coursemod”.

  • I use this to affect the course value, which is computed by using “longrodscale” variable that can be modified by the user, and multiplying it by “coursemod”. This give me “course”.

  • I then have to use a temp variable to store this, and retrieve the transform.position of my piston axis, so I can alter it.

After many minutes or hours I’ve lost count, I came to the conclusion that I have no idea how to fix this behavior and I am not sure what exactly is causing it. If anyone has experienced anything like it let me know, any hint is welcome.

Fattie is absolutely right, the vertical movement is not a pure sine curve. Here, i made a quick sketch :wink: The point is that the red line (L1) has a fix length, but it’s not parallel to the movement axis (except at the top and bottom point). You need to calculate the projection of L1 onto the movement axis and add it to the cos-position (or sin depending on where you start counting)


However i guess your problem is that you shouldn’t use eulerAngles this way. EulerAngles are caculated from a Quaternion and might not represent the angle you would expect due to gimbal lock avoidance.

You should use a float variable as angle that you adjust yourself. You can rotate the axis also by this angle. Never rely on an angle returned by eulerAngles.