- Home /
[SOLVED] Derive an equation from a graph?
I am trying to figure out a formula to apply as my mechanic. My user gives in One Input and I should apply it as two outputs. i.e. two output forces
I have sketched a graph depicting how I need the forces to be. But I am not able to figure out a way to derive an equation to find it out.
The input is basically a tilt and the amount of tilt is calculated to apply force.
Can you guys help me to derive a equation for this?
THE GRAPH
Same image is also here, just in case.
Thank you,
Karsnen.
Just to check... are there any curves involved, or are both forces entirely linear?
I think for this kind of thing, you may be better suited using Animation Curves than an equation. Then it becomes flexible which would be handy for tweaking values associated with force.
Screenhog : They are not linear. They are more like to be a curve.
Alucardj : I am sorry, I am not able to get you.
Basically it is a window like the animation window, you add nodes and form curves, then ask to evaluate at position X, and it returns value at position Y. I think it may be better if I make an answer with a script to demonstrate. Here's the API links :
http://docs.unity3d.com/Documentation/ScriptReference/AnimationCurve.html
http://docs.unity3d.com/Documentation/ScriptReference/AnimationCurve.Evaluate.html
So can I use them as a catalyst between my input and the output? I thought they serve only for particle effects, sounds and animation of meshes.
Answer by AlucardJay · Sep 20, 2012 at 06:06 PM
Attach this script to any gameObject. Note in the inspector 2 rectangular windows with the assigned var names. Click on a window. You are now in the curve editor. Select one of the preset curves at the bottom, then add / remove / move / rotate nodes to form curves.
I personally like to keep my values 'normalized' i.e. on the positive axis between 0 and 1. But as long as you know what range you are accessing and keep that in mind when forming your curves, there shouldn't be a problem. Infact from memory I once called a value x that had no curve that high, and it returned 0, but definitely no error. Have a play around. If you read x as time % 1 and affect a transform of a cube, you'll have a visual representation of how the curve is read. ut basically for a 2D graph it is give me Y for value X
#pragma strict
public var curveForceA : AnimationCurve;
public var curveForceB : AnimationCurve;
public var valueX : float;
function Update()
{
if ( Input.GetMouseButtonUp(0) )
{
var curveA : float = curveForceA.Evaluate( valueX );
Debug.Log( " Force A returned " + curveA );
var curveB : float = curveForceB.Evaluate( valueX );
Debug.Log( " Force B returned " + curveB );
}
}
I took a while typing the description =]
http://docs.unity3d.com/Documentation/ScriptReference/AnimationCurve.html
http://docs.unity3d.com/Documentation/ScriptReference/AnimationCurve.Evaluate.html
I have written an example of a curve reader, this can be done without playing the scene. YOu need to change the script, typecast the variables to the names of your scripts, and also name the curves the same as the var names in the script to be copied.
So for my example, the script to be copied is CurvesExample, it is the above script.
I have an empty gameObject with a script called CurvesBackup1, this is all that is on it :
#pragma strict
public var curveForceA : AnimationCurve;
public var curveForceB : AnimationCurve;
function Start() {
}
function Update() {
}
And finally an empty gameobject with the script reader. Drag and drop the example object and the backup object in the inspector, then right-click on the inspector and select "Read Curves"
The curve window don't update straight away, you have to click off the object and then back on. Check the backup object has the curves copied to it, including the changes in tangent handles.
To write a curve to a script, just reverse-engineer the below to read from backup, and write to the script using. Here is the read script :
#pragma strict
#if UNITY_EDITOR
public var scriptExample : CurvesExample;
public var scriptBackup : CurvesBackup1;
public var curveForceA : AnimationCurve;
public var curveForceB : AnimationCurve;
private var ks : Keyframe[];
@ContextMenu ("Read Curves")
function ReadCurves()
{
Debug.Log("Reading Curves from ContextMenu");
// curveForceA
ks = new Keyframe[ scriptExample.curveForceA.length ];
for ( var i:int = 0; i < scriptExample.curveForceA.length; i ++ )
{
ks[i] = Keyframe( scriptExample.curveForceA[i].time,
scriptExample.curveForceA[i].value,
scriptExample.curveForceA[i].inTangent,
scriptExample.curveForceA[i].outTangent );
}
curveForceA = new AnimationCurve( ks ); // Read and Store Curves from scriptExample
scriptBackup.curveForceA = new AnimationCurve( ks ); // Write Curves to scriptBackup
// curveForceB
ks = new Keyframe[ scriptExample.curveForceB.length ];
for ( i = 0; i < scriptExample.curveForceB.length; i ++ )
{
ks[i] = Keyframe( scriptExample.curveForceB[i].time,
scriptExample.curveForceB[i].value,
scriptExample.curveForceB[i].inTangent,
scriptExample.curveForceB[i].outTangent );
}
curveForceB = new AnimationCurve( ks ); // Read and Store Curves from scriptExample
scriptBackup.curveForceB = new AnimationCurve( ks ); // Write Curves to scriptBackup
}
#endif
to use @ContextMenu, right-click where it says Curves Reader (Script) in bold :
For the transform, add this at the start :
var theCube : Transform;
and in the function :
theCube.position.x = curveForceA.Evaluate( Time.time % 1.0 );
$$anonymous$$ $$anonymous$$ay aka alucardj - thank you. I would trying it out.
fantastic example introducing "the curve thingy" to the world, awesome
It just works like a beauty.. Just did even think about this. Thanks $$anonymous$$ $$anonymous$$ay.
I have one more concern. I am not able to save the curve. I declare the variable and then alter the curves inside the inspector pane. Then if I
Use the same script on a different gameobject (or)
Change the variable names
I lose the curve. I predicted this happening but is there a way to save them?
$$anonymous$$ $$anonymous$$ay - hmm Yeah sure.. I am going to work on that whenever I could. If I happen to get one I will let you know for sure. But for the moment, the temp solution I take is to record all (x,y) key point values and a screen shot of the curve. This helps a bit not comprehensive.
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
How good is my "Quaternion" code efficiency? 1 Answer
How to successfully apply force calling a function from another script 1 Answer
Multiple Cars not working 1 Answer
Why is Input.GetAxisRaw() not returning whole numbers when using a joystick? 1 Answer