Smoothstep function - c++

I'm trying to get some results to plot on a graph by using the Smoothstep function provided by AMD which was fount on this Wikipedia page Smoothstep. Using the;
A C/C++ example implementation provided by AMD[4] follows.
float smoothstep(float edge0, float edge1, float x)
{
// Scale, bias and saturate x to 0..1 range
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
// Evaluate polynomial
return x*x*(3 - 2 * x);
}
The problem is that I am not able to use this method due to the static method clamp not being available.
I have imported the following;
#include <math.h>
#include <cmath>
#include <algorithm>
Yet there is no clamp method defined.
My maths skill is not the best, but is there a way to implement the Smoothstep function just like there is way to implement a LERP function;
float linearIntepolate(float currentLocation, float Goal, float time){
return (1 - time) * currentLocation + time * Goal;
}

Perhaps it was just the namespace "std" which was missing : here is my code that compile :
#include <algorithm>
float smoothstep(float edge0, float edge1, float x) {
// Scale, bias and saturate x to 0..1 range
x = std::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
// Evaluate polynomial
return x * x * (3 - 2 * x);
}

Related

Proper sphere collision resolution in C++

I am implementing a sphere to sphere collision resolution and I am a little confused on where to start. First question, is there a standard way that games/engines do sphere to sphere collision resolution? Is there only like a couple standard ways to do it? Or does the resolution vary very heavily based on whats needed?
I want to implement this in my engine and I wrote a basic one that pushes a sphere and another sphere (so basically the one interacting can push the other) but this was just a super simple concept. How exactly can I improve this to make it more accurate? (Mind you the code isn't optimized since I am still testing)
It seems like there is a lack of solid documentation on collision resolution in general as it's a more niche topic. Most resources I found only concern the detection part.
bool isSphereInsideSphere(glm::vec3 sphere, float sphereRadius, glm::vec3 otherSphere, float otherSphereRadius, Entity* e1, Entity* e2)
{
float dist = glm::sqrt((sphere.x - otherSphere.x) * (sphere.x - otherSphere.x) + (sphere.y - otherSphere.y) * (sphere.y - otherSphere.y) + (sphere.z - otherSphere.z) * (sphere.z - otherSphere.z));
if (dist <= (sphereRadius + otherSphereRadius))
{
//Push code
e1->move(-e1->xVelocity / 2, 0, -e1->zVelocity / 2);
e2->move(e1->xVelocity / 2, 0, e1->zVelocity / 2);
}
return dist <= (sphereRadius + otherSphereRadius);
}
Using std::sqrt is unnecessary and it's probably a lot quicker to compare the squared length against (sphereRadius + otherSphereRadius)2.
Example:
#include <glm/glm.hpp>
#include <iostream>
#include <cstdlib>
auto squared_length(const glm::vec3& v) {
return std::abs(v.x * v.x + v.y * v.y + v.z * v.z);
}
class Sphere {
public:
Sphere(const glm::vec3& Position, float Radius) :
position{Position}, radius(Radius) {}
bool isSphereInsideSphere(const Sphere& other) const {
auto dist = squared_length(position - other.position);
// compare the squared values
if(dist <= (radius + other.radius) * (radius + other.radius)) {
// Push code ...
return true;
}
return false;
}
private:
glm::vec3 position;
float radius;
};
int main() {
Sphere a({2, 3, 0}, 2.5);
Sphere b({5, 7, 0}, 2.5);
std::cout << std::boolalpha << a.isSphereInsideSphere(b) << '\n'; // prints true
}
Here is a simpler example (without involving new classes).
bool isSphereInsideSphere(glm::vec3 sphere, float sphereRadius, glm::vec3 otherSphere, float otherSphereRadius, Entity* e1, Entity* e2)
{
auto delta = otherSphere - sphere;
auto r2 = (sphereRadius + otherSphereRadius)*(sphereRadius + otherSphereRadius);
if (glm::dot(delta,delta) <= r2)
{
//Push code
return true;
}
return false;
}

Multiply two complex number on GPU using OpenCL

I'm trying to write a OpenCL based code to calculate exp() of some complex numbers on GPU using the following kernel function:
#include <complex.h>
inline float complex exp(float complex z) {
return (exp(__real__(z)) * (cos(__imag__(z)) + sin(__imag__(z))*I ));
}
__kernel void
calculate(__global float * c)
{
int nIndex = get_global_id(0);
float complex rays = 1.0f + 1.0f * I;
float complex ans = exp(rays);
c[nIndex] = __real__(ans * ans);
}
But I get the following error:
ASSERTION FAILED: I.hasStructRetAttr() == false
The * works well with other complex numbers but it produce error for multiplying exp() functions output. Also I use + and - operators with exp() functions output without any problem. Just I have problem with * and / operators.

C++ Convert 3D Velocity Vector To Speed Value

In a game I am working on I get the velocity of a game world object like so
void getObjectVelocity(int objectID, vec3_t *velocityOut);
So if I were to call this function like this
vec3_t storeObjectVelocity;
getObjectVelocity(21/* just an example ID */, &storeObjectVelocity);
The velocity of the object with the ID of 21 would be stored in storeObjectVelocity.
For testing purposes I am trying to print the speed of this object based off it's velocity in the middle of the game screen.
Here's an example just to give you a better idea of what I'm trying to accomplish
int convertVelocityToSpeed(vec3_t velocity)
{
//This is where I am having issues.
//Converting the objects 3D velocity vector to a speed value
}
int testHUDS()
{
char velocityToSpeedBuffer[32] = { 0 };
vec3_t storeObjectVelocity;
getObjectVelocity(21, &storeObjectVelocity);
strcpy(velocityToSpeedBuffer, "Speed: ");
strcat(velocityToSpeedBuffer, system::itoa(convertVelocityToSpeed(storeObjectVelocity), 10));
render::text(SCREEN_CENTER_X, SCREEN_CENTER_Y, velocityToSpeedBuffer, FONT_SMALL);
}
Here is my vec3_t struct in case you were wondering
struct vec3_t
{
float x, y, z;
};
Length of a vector is calculated as
√( x² + y² + z²)
So in your program, something like this will works:
std::sqrt( velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z )
As #Nelfeal commented, last approach can overflow. Using std::hypot this problem is avoided. Since is more secure and it's clearer, this should be the first option if C++17 is available. Even knowing that it's less efficient. Remember to avoid premature micro optimizations.
std::hypot(velocity.x, velocity.y, velocity.z)
Also, you should think about passing velocity as a const reference to the function.
Speed is a scalar quantity given by the magnitude of a velocity vector |velocity|. Magnitude of a 3D vector is computed as:
So in your code you want to implement your method as:
int convertVelocityToSpeed(vec3_t velocity)
{
return std::sqrt(velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z);
}
you may need to include the math header #include <cmath> and I have assumed your vec3_t holds int values although this is unusual for a velocity in physics simulations, they are usually floating point types. If not you need to check your return type.
#include <cmath>
using namespace std;
sqrt(pow(velocity.x,2), pow(velocity.y,2), pow(velocity.x,2));
Use sqrt from cmath and pow from cmath.
EDIT
edited the mistype import as corrected by in the comments

How to get the angle (pitch/yaw) between two 3D vectors for an autoaim

I'm trying to get the angles between two vectors (My Camera Position and Enemy Position) to create an autoaim/aimbot.
The game is Unity based, it uses the left handed coordinate system. X Y Z is right, up, forward.
The game also uses degrees.
Here is the pseudocode I am trying but its failing to give me the proper pitch/yaw.
diff = camera_position - enemy_position
hypotenuse = sqrt(diff.x*diff.x + diff.y*diff.y)
angle.x = asinf(diff.z / hypotenuse) * (180 / PI);
angle.y = atan2(diff.y / diff.x) * (180 / PI);
angle.z = 0.0f;
Can someone help me with this? I am terrible at math.
I'm trying to get the angles between two vectors (My Camera Position
and Enemy Position)
In Unity:
Use the Angle function from Vector3 structure.
float angle = Vector3.Angle(camera_position, enemy_position);
Or Individual angles:
float angleX = Vector3.Angle(new Vector3(camera_position.x, 0, 0), new Vector3(enemy_position.x, 0, 0));
float angleY = Vector3.Angle(new Vector3(0, camera_position.y, 0), new Vector3(0, enemy_position.y, 0));
float angleZ = Vector3.Angle(new Vector3(0, 0, camera_position.z), new Vector3(0, 0, enemy_position.z));
EDIT:
I'm not using the Unity engine. This is a separate module I am
creating to rig my own autoaim. I'm trying to do get the proper math
itself.
In C++:
The code is explained in the Angle function below which is the last function
#include <iostream>
#include <numeric> //for inner_product
#include <vector> //For vector
#include <math.h> //For sqrt, acos and M_PI
float Dot(std::vector<float> lhs, std::vector<float> rhs);
float magnitude(std::vector<float> vec3);
float Angle(std::vector<float> from, std::vector<float> to);
std::vector<float> normalise();
int main()
{
std::vector<float> from{3, 1, -2};
std::vector<float> to{5, -3, -7 };
float angle = Angle(from,to);
std::cout<<"Angle: "<<angle<<std::endl;
return 0;
}
//Find Dot/ Scalar product
float Dot(std::vector<float> lhs, std::vector<float> rhs){
return std::inner_product(lhs.begin(), lhs.end(), rhs.begin(), 0);
}
//Find the magnitude of the Vector
float magnitude(std::vector<float> vec3)//<! Vector magnitude
{
return sqrt((vec3[0] * vec3[0]) + (vec3[1] * vec3[1]) + (vec3[2] * vec3[2]));
}
//Normalize Vector. Not needed here
std::vector<float> normalise(std::vector<float> vect)
{
std::vector<float> temp{0, 0, 0};
float length = magnitude(vect);
temp[0] = vect[0]/length;
temp[1] = vect[1]/length;
temp[2] = vect[2]/length;
return temp;
}
float Angle(std::vector<float> from, std::vector<float> to){
//Find the scalar/dot product of the provided 2 Vectors
float dotProduct = Dot(from, to);
//Find the product of both magnitudes of the vectors then divide dot from it
dotProduct = dotProduct / (magnitude(from) * magnitude(to));
//Get the arc cosin of the angle, you now have your angle in radians
float arcAcos = acos(dotProduct);
//Convert to degrees by Multiplying the arc cosin by 180/M_PI
float angle = arcAcos * 180 / M_PI;
return angle;
}
To calculate the angle between two 3d coordinates, in degrees you can use this CalcAngle Function:
#include <algorithm>
#define PI 3.1415927f
struct vec3
{
float x, y, z;
}
vec3 Subtract(vec3 src, vec3 dst)
{
vec3 diff;
diff.x = src.x - dst.x;
diff.y = src.y - dst.y;
diff.z = src.z - dst.z;
return diff;
}
float Magnitude(vec3 vec)
{
return sqrtf(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
}
float Distance(vec3 src, vec3 dst)
{
vec3 diff = Subtract(src, dst);
return Magnitude(diff);
}
vec3 CalcAngle(vec3 src, vec3 dst)
{
vec3 angle;
angle.x = -atan2f(dst.x - src.x, dst.y - src.y) / PI * 180.0f + 180.0f;
angle.y = asinf((dst.z - src.z) / Distance(src, dst)) * 180.0f / PI;
angle.z = 0.0f;
return angle;
}
Complications:
Not all games use the same technique for angles and positions. Min and Max values for x, y and z angles can be different in every game. The basic idea is the same in all games, they just require minor modification to match each game. For example, in the game the code was written for, the X value has to be made negative at the end for it to work.
Another complication is X, Y and Z don't always represent the same variables in both coordinates and angle vec3s.

What's wrong with my C++ code?

I'm trying to create an equilateral triangle that outputs to the console but my code seems to output the triangle at point 0,0.
How can I fix this?
this is what I have:
Header file:
#include "shape.h"
#include "vertex.h"
#include <list>
// An equilateral triangle
class Triangle : public Shape
{
// the radius provides the length of a side
// and enables a vertex to be plotted from
// which the other two vertices can be derived
// via rotation
int radius;
public:
// constructor
Triangle(Vertex point, int radius = 10);
// calculates and returns a triangle's area
int area();
// calculates and returns a triangle's perimeter
int perimeter();
};
and the cpp file
#include "triangle.h"
#include "vertex.h"
#include <list>
Triangle::Triangle(Vertex point, int radius) : Shape(point)
{
this->radius = radius;
this->centroid = Vertex(0,0);
vertices.push_back(Vertex(centroid.getY() + radius));
vertices.push_back(Vertex(centroid.getY() + (radius*2)));
vertices.push_back(Vertex(centroid.getX() * cos(120) - centroid.getY() * sin(120),centroid.getY() * cos(120) + centroid.getX() * sin(120)));
vertices.push_back(Vertex(centroid.getX() * cos(240) - centroid.getY() * sin(240),centroid.getY() * cos(240) + centroid.getX() * sin(240)));
this->centroid = point;
}
// returns the area of an equilateral triangle
int Triangle::area()
{
return radius*radius*(sqrt(3)/4);
}
// returns the perimeter of an equilateral triangle
int Triangle::perimeter()
{
return radius *3;
}
I'm not sure what's wrong with it. I have tried many different ways to fix it but I have had no luck in doing so. can somebody please help?
sin, cos, etc use radians, not degrees.
Also you set your centroid at a hard-coded 0,0.
As noted in the other answer, sin and cos take their arguments in radians, not degrees.
Furthermore, your constructor seems strange. Bear in mind that I don't have all the details behind your code (Vertex, Shape, ...), but assuming that vertices needs to contain the three vertices of your triangle and that Vertex has a constructor taking the three coordinates, I'd try something like this:
Triangle::Triangle(Vertex point, int radius) : Shape(point)
{
this->radius = radius;
// in any case, you want the traingle to be centered around the point given as input
this->centroid = point;
// we can just avoid calling trigonometric functions at runtime
// also, the values for these particular angles are well-known, so we don't need to call any actual trigonometric functions
static const float COS_60 = 0.5f;
static const float COS_30 = 0.5f * sqrt(3.f);
// compute the length of the side of the triangle based on its radius
// for instance, using any of the six right triangles between the center, a vertice and the projection of the center against one of the sides
const float side = radius * 2.f * COS_30;
// more basic geometry
const float bottomHeight = point.getY() - COS_60 * radius;
// first vertice is right above the center
this->vertices.push_back(Vertex(point.getX(), point.getY() + radius));
// second vertice is at the bottom height, and its X position is offset by half the side
this->vertices.push_back(Vertex(point.getX() + COS_60 * side, bottomHeight));
// same, but in the other direction
this->vertices.push_back(Vertex(point.getX() - COS_60 * side, bottomHeight));
}