Hello I am trying to visualize an Aizawa attractor and it's seems to work at first but then just stabilizes at zero/stops moving. I have looked at several implementations online and mine seems to be the same but I don't know why it stops moving.
Here's the code which takes in a point and returns the new point:
public class Aizawa
{
private const float a = 0.95f;
private const float b = 0.7f;
private const float c = 0.6f;
private const float d = 3.5f;
private const float e = 0.25f;
private const float f = 0.1f;
public static void Iterate(float x, float y, float z, out float dX, out float dY, out float dZ)
{
dX = ((z - b) * x - d * y);
dY = (d * x + (z - b) * y);
dZ = (c + a * z - ((z * z * z) / 3f) - (x * x + y * y) * (1f + e * z) + f * z * x * x * x);
}
}
After this I just set the point as follows:
_xPos += dX * time;
_yPos += dY * time;
_zPos += dZ * time;
I'm using unity to visualize it and here is the result so far:
screenshot
I have no idea where to go from here! Any help would be appreciated
Cheers
Related
How to make the GPS algorithm to get a point based on three known points and their distances?
It is made in Unity, so it uses the Vector3 and Mathf classes, but it would be easy to remove those dependencies using a 3-sized array for each point and the standart Math class.
static float sqr(float a)
{
return a * a;
}
static float norm(Vector3 a)
{
return Mathf.Sqrt(sqr(a.x) + sqr(a.y) + sqr(a.z));
}
static float dot(Vector3 a, Vector3 b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
static Vector3 vector_cross(Vector3 a, Vector3 b)
{
return new Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}
public static Vector3[] Trilaterate(Vector3 p1, float r1, Vector3 p2, float r2, Vector3 p3, float r3)
{
Vector3 ex = (p2 - p1) / norm(p2 - p1);
float i = dot(ex, (p3 - p1));
Vector3 a = ((p3 - p1) - (ex * i));
Vector3 ey = (a / norm(a));
Vector3 ez = vector_cross(ex, ey);
float d = norm(p2 - p1);
float j = dot(ey, p3 - p1);
float x = (sqr(r1) - sqr(r2) + sqr(d)) / (2 * d);
float y = (sqr(r1) - sqr(r3) + sqr(i) + sqr(j)) / (2 * j) - (i / j) * x;
float b = sqr(r1) - sqr(x) - sqr(y);
// floating point math flaw in IEEE 754 standard
// see https://github.com/gheja/trilateration.js/issues/2
if (Mathf.Abs(b) < 0.0000000001)
{
b = 0;
}
float z = Mathf.Sqrt(b);
// no solution found
if (float.IsNaN(z))
{
return new Vector3[] { Vector3.zero };
}
Vector3 aa = p1 + ((ex * x) + (ey * y));
Vector3 p4a = (aa + (ez * z));
Vector3 p4b = (aa - (ez * z));
return new Vector3[] { p4a, p4b };
}
It is a direct translation of the JS version from gheja, all credits to them: https://github.com/gheja/trilateration.js/blob/master/trilateration.js
So unlike everyone here, I'm trying to find the intersections from circle-line collision.
The points are taken from the user input.
float cx; //circle center x
float cy; //circle center y
float px; //point x
float py; //point y
float vx; //vector x
float vy; //vector y
float vySq = vy * vy;
float vxSq = vx * vx;
float cxSq = cx * cx;
float rSq = r * r;
float thatPart = ( ( (vy * px) / vx) + py - cy); //so I don't have to re-type it 3 different times
float a = 1 + (vySq/vxSq);
float b = (2 * cx) + ( (2 * vy) * thatPart / vx);
float c = cxSq + ( thatPart * thatPart ) - rSq;
float x1 = QUADRATIC(a, b, c, true);
float x2 = QUADRATIC(a, b, c, false);
float y1 = ((vy * x1) - (vy * px) + (vx * py)) / vx;
float y2 = ((vy * x2) - (vy * px) + (vx * py)) / vx;
My QUADRATIC function 100% works, so I am not worried about that.
It's a, b, and c. I receive the wrong values for them. And all this math is based on a pdf given in math class. (here)
So... what am I doing wrong?
Thanks.
The equations in both the PDF and the source code seem unnecessarily complicated, so I will re-establish them in a clenear way (or at least one that pleases me).
The vector from the center of the circle to any point S on the line can be written as
CS = CP + t V
where t is an arbitrary parameter.
S belongs to the circle when
CS² = R² = (CP + t V)²
giving the quadratic equation in t:
V² t² + 2 CP.V t + CP² - R² = 0
When you have the values of t, plug in the first equation.
Math Treatment
You have a line with coordinates (x,y) = (px + vx*t, py + vy*t) where t is an arbitrary parameter.
The line intersects the circle when its coordinates solve x^2 + y^2 = r^2.
This leads to the following quadratic equation, to be solved for t.
t^2 + 2*t*b + a = 0
a = (px^2+py^2-r^2)/(vx^2+vy^2)
b = (px*vx+py*vy)/(vx^2+vy^2)
The two solutions are:
t = -b ± sqrt(b^2-a)
Use the two t values into (x,y) to get the coordinates.
Sample Code
static class Program
{
static void Main(string[] args)
{
var ray = new Ray() {
Point = new Vector2(-3, 1),
Direction = new Vector2(2, 0.5f)
};
var circle = new Circle
{
Center = new Vector2(1, 1),
Radius = 4
};
var points = Geometry.Intersect(circle, ray);
if(points.Length>0)
{
foreach(var point in points)
{
Console.WriteLine(point.ToString());
}
}
else
{
Console.WriteLine("Circle and Ray do not intersect");
}
}
}
Object Oriented Models
public class Circle
{
public Vector2 Center { get; set; }
public float Radius { get; set; }
}
public class Ray
{
public Vector2 Point { get; set; }
public Vector2 Direction { get; set; }
public Vector2 Along(float t)
{
return Point + t*Direction;
}
}
public static class Geometry
{
public static Vector2[] Intersect(Circle circle, Ray ray)
{
float a = (ray.Point.LengthSquared()-circle.Radius*circle.Radius)/ray.Direction.LengthSquared();
float b = Vector2.Dot(ray.Point, ray.Direction)/ray.Direction.LengthSquared();
if(b*b-a>0)
{
// two intersection points
float t1 = -b-(float)Math.Sqrt(b*b-a);
float t2 = -b+(float)Math.Sqrt(b*b-a);
return new Vector2[] {
ray.Along(t1),
ray.Along(t2),
};
}
else if(b*b-a==0)
{
// one intersection point
float t = -b;
return new Vector2[] { ray.Along(t) };
}
else
{
// no intersection, return empty array
return new Vector2[0];
}
}
}
NOTE: Code uses System.Numerics library
What is the best way to decelerate at a speed of any given value (e.g. accelerationDropOff = 1.5f) before it reaches the end destination?
public bool MoveFromCurrentToPosition(float x, float y, float velocity, float acceleration, float deltaTime)
{
float startX = positionX, startY = positionY;
float endX = x, endY = y;
float deltaX = endX - startX;
float deltaY = endY - startY;
float speed = velocity;
float elapsed = 0.01f;
// On starting movement
float distance = (float)Math.Sqrt(Math.Pow(deltaX, 2) + Math.Pow(deltaY, 2));
float directionX = deltaX / distance;
float directionY = deltaY / distance;
isMoving = true;
// On update
if (isMoving == true)
{
positionX += directionX * speed * elapsed;
positionY += directionY * speed * elapsed;
if (currentAcceleration == 0)
{
currentAcceleration = acceleration;
}
else if (currentAcceleration >= maxAcceleration) // <- Don't accelerate anymore
{
speed *= currentAcceleration;
positionX += (directionX * speed) * deltaTime; positionY += (directionY * speed) * deltaTime;
bounds.X = (int)positionX; bounds.Y = (int)positionY;
}
else
{
currentAcceleration += acceleration;
speed *= currentAcceleration;
positionX += (directionX * speed) * deltaTime; positionY += (directionY * speed) * deltaTime;
bounds.X = (int)positionX; bounds.Y = (int)positionY;
}
float a = x, o = y;
double angle = Math.Atan2(o, a);
angle = angle * 180 / Math.PI;
movementDirection = (float)(180 - angle);
// Decelerate before reaching the end point
if (Math.Sqrt(Math.Pow(positionX - startX, 2) + Math.Pow(positionY - startY, 2)) >= distance)
{
positionX = endX;
positionY = endY;
isMoving = false;
return true;
}
}
return false;
}
I have been stuck on this problem for a hour or two and Math.exe is not responding. Can anyone point me in the correct direction please?
It seems as if you are mixing up speed (velocity) and acceleration. Speed is the change of position with respect to a given time frame. Acceleration is the change of speed with respect to a given time frame. For a constant acceleration, position and velocity change as follows:
v1 = v0 + a * t
x1 = x0 + v0 * t + 1/2 * a * t^2
v0, v1 and x0, x1 are the velocities and positions at the beginning and end of the time frame, respectively, a is the acceleration, t is the time frame length. This is the exact formula if you assume constant acceleration over the period of the time frame. Often, you find approximations like the following, which introduce some integration errors:
v1 = v0 + a * t
x1 = x0 + v1 * t
I would suggest to use the exact formulas.
As far as I understand your question, you want to find an acceleration, such that a body moving at initial velocity v0 stops after travelling d length units.
This gives you the following equations:
0 = v0 + a * t //target velocity of 0
d = 0 + v0 * t + 1/2 * a * t^2 //travel distance of d
The solution is:
a = -1/2 * v0^2 / d
The time needed for this motion is:
t = 2 * d / v0
So calculate the acceleration once at the beginning of the deccelerating movement and then update current position and velocity with the formulas above.
Some additional hints for your code:
If you want to square a variable x, use x * x instead of Math.pow(x, 2). It is easier to read and has a better performance.
If you already use XNA, then use its Vector2 structure. This makes a lot of things much easier. You can just add two vectors and don't need to care about each component separately. There are methods to get the length of a vector, and so on.
So I'm trying to use the haversine formula in Unity to get the distance between two different points (latitude and longitud given). The code is working (no errors) but I keep gettting a wrong result. I followed the entire formula so I don't really know where the math/code problem is. Any idea?
Here's the code:
public float lat1 = 42.239616f;
public float lat2 = -8.72304f;
public float lon1 = 42.239659f;
public float lon2 = -8.722305f;
void operacion(){
float R = 6371000; // metres
float omega1 = ((lat1/180)*Mathf.PI);
float omega2 = ((lat2/180)*Mathf.PI);
float variacionomega1 = (((lat2 - lat1)/180)*Mathf.PI);
float variacionomega2 = (((lon2 - lon1) / 180) * Mathf.PI);
float a = Mathf.Sin(variacionomega1/2) * Mathf.Sin(variacionomega1/2) +
Mathf.Cos(omega1) * Mathf.Cos(omega2) *
Mathf.Sin(variacionomega2/2) * Mathf.Sin(variacionomega2/2);
float c = 2 * Mathf.Atan2(Mathf.Sqrt(a), Mathf.Sqrt(1-a));
float d = R * c;
}
I think this line is incorrect:
float c = 2 * Mathf.Atan2(Mathf.Sqrt(a), Mathf.Sqrt(1-a));
UPDATED:
The correct way would be:
float c = 2 * Mathf.Asin(Mathf.Sqrt(a));
I need to make a picture box to lerp from position to position (like you can do that in unity).
How can I do that , is there a built-in function?
thanks :)
Linear interpolation (lerp) is actually a pretty easy function to implement. The equation is
float Lerp(float firstFloat, float secondFloat, float by)
{
return firstFloat * (1 - by) + secondFloat * by;
}
A higher order Lerp just wraps lower order lerps:
Vector2 Lerp(Vector2 firstVector, Vector2 secondVector, float by)
{
float retX = Lerp(firstVector.x, secondVector.x, by);
float retY = Lerp(firstVector.y, secondVector.y, by);
return new Vector2(retX, retY);
}
The DirectX SDK has all manner of math functions like Unity, but that's a lot of overhead to bring in just for Lerp. You're probably best off just implementing your own.
Greg Bahm wrote inverted lerp equation firstFloat * by + secondFloat * (1 - by), where firstFloat is the secondFloat and secondFloat is the firstFloat.
In fact, corrent lerp equation is:
firstFloat * (1 - by) + secondFloat * by
But the fastest way to linear interpolation is:
firstFloat + (secondFloat - firstFloat) * by
That's 2 additions/subtractions and 1 multiplication instead of 2 addition/subtractions and 2 multiplications.
Lerp for Vector2 is correct.
Also, the fastest way is less precise (thank you, cid):
Imprecise method, which does not guarantee v = v1 when t = 1, due to floating-point arithmetic error. This method is monotonic
This form may be used when the hardware has a native fused multiply-add instruction.
https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support
Try this instead
float Lerp(float a, float b, float t)
{
//return firstFloat * by + secondFloat * (1 - by);
return (1f - t) * a + t * b;
}
PointF Lerp(PointF a, PointF b, float t)
{
float retX = Lerp(a.X, b.X, t);
float retY = Lerp(a.Y, b.Y, t);
return new PointF(retX, retY);
}
public static float CubicInterpolation(float v0, float v1, float v2, float v3, float t) {
//var v01 = Lerp( v0, v1, t );
//var v12 = Lerp( v1, v2, t );
//var v23 = Lerp( v2, v3, t );
//var v012 = Lerp( v01, v12, t );
//var v123 = Lerp( v12, v23, t );
//return Lerp( v012, v123, t );
var p = (v3 - v2) - (v0 - v1);
var q = (v0 - v1) - p;
var r = v2 - v0;
var s = v1;
return (p * t * 3) + (q * t * 2) + (r * t) + s;
//var r = 1f - t;
//var f0 = r * r * r;
//var f1 = r * r * t * 3;
//var f2 = r * t * t * 3;
//var f3 = t * t * t;
//return (v0 * f0) + (v1 * f1) + (v2 * f2) + (v3 * f3);
}
public static float QuadraticInterpolation(float v0, float v1, float v2, float t) {
var v01 = Lerp( v0, v1, t );
var v12 = Lerp( v1, v2, t );
return Lerp( v01, v12, t );
}
public static float Lerp(float v1, float v2, float t) {
return v1 + ((v2 - v1) * t);
}
public static float CosInterpolation(float t) {
t = (float) -Math.Cos( t * Math.PI ); // [-1, 1]
return (t + 1) / 2; // [0, 1]
}
public static float PerlinSmoothStep(float t) {
// Ken Perlin's version
return t * t * t * ((t * ((6 * t) - 15)) + 10);
}
public static float SmoothStep(float t) {
return t * t * (3 - (2 * t));
}