Graal Forums  

Go Back   Graal Forums > Development Forums > NPC Scripting > New Scripting Engine (GS2)
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 01-19-2011, 12:49 AM
dabblercody dabblercody is offline
Tech Assistant
dabblercody's Avatar
Join Date: May 2006
Location: Florida
Posts: 22
dabblercody is on a distinguished road
Beiser Curves

I've recently been trying to figure how to correctly implement this into Graal. I've also been trying to improve my math-based scripting. This is a sample script I had to test the outcome of the 4 given points. The solution I get is x1 and x2 = 5.82375. I just need to find out if this is correct? And if it isn't what is the correct way of doing it, and how can I improve onto my knowledge of scripting? In case your wondering how I got the variable t. And yes I spelled Beiser wrong it should be Bezier.

The t parameter (varying from 0 to 1) cuts the P1-P4 segment to intervals, according to the wanted accuracy.
When t = 0 results are t(x1) = P1(x1) and t(x2)= P1(x2)
When t = 1 results are t(x1) = P4(x1) and t(x2)= P4(x2)


PHP Code:
//#CLIENTSIDE
function onPlayerChats()
{
 if (
player.chat == "/curve")
 {
  
Beiser2D();
 }
}

function 
Beiser2D()
{
 
.05;
 
5;  // p1
 
10// p2
 
25// p3
 
40// p4
 
x1 = (t)^* (t)^* (t) * t^t^d;
 
x2 = (t)^* (t)^* (t) * t^t^d;
 
player.chat "Solution is:" SPC x1 SPC "/" SPC x2;

The Formulas are:
PHP Code:
t(x1) = (1-t)3  x P1x 3 x (1-t)2 x t x P2x 3 x (1-tx t2 x P3x t3 x P4x 
t
(x2) = (1-t)3  x P1y 3 x (1-t)2 x t x P2y 3 x (1-tx t2 x P3y t3 x P4y 
__________________
Dabbler

"Our work is the presentation of our capabilities."
- Goethe, Johann Wolfgang Von

Last edited by dabblercody; 01-19-2011 at 01:10 AM..
Reply With Quote
  #2  
Old 01-19-2011, 01:30 AM
fowlplay4 fowlplay4 is offline
team canada
fowlplay4's Avatar
Join Date: Jul 2004
Location: Canada
Posts: 5,200
fowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond repute
Well first off, throw temp in front of variables that are only going to be used locally otherwise they're declared globally which is just annoying.

You should modify it so you can call the function and get the result from it. I.e:

PHP Code:
//#CLIENTSIDE
function onCreated() {
  
temp.val calc(12);
  
player.chat temp.val;
}

function 
calc(ab) {
  
temp.result b;
  return 
temp.result;

After you modify your formulas to work with coordinates since p1...4 = {x, y} and calculate using the respective coordinate in each formula. I.e:

PHP Code:
temp.nx = (t)^a[0] + * (t)^b[0] + * (t) * t^c[0] + t^d[0];
temp.ny = (t)^a[1] + * (t)^b[1] + * (t) * t^c[1] + t^d[1];
return {
temp.nxtemp.ny}; 
The parameters for this will probably be something like..

PHP Code:
function calc_bezier(tabcd) {
  
// your calculations

Also check out the diagrams here:
http://en.wikipedia.org/wiki/Bézier_curve
__________________
Quote:
Reply With Quote
  #3  
Old 01-19-2011, 01:50 AM
WhiteDragon WhiteDragon is offline
Banned
Join Date: Feb 2007
Posts: 1,002
WhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to behold
A point is not a number, it is a pair of numbers. Which means how you wrote a, b, c, and d is wrong.

Points also have slightly different multiplication and addition rules than numbers... given two points P1 = (X1, Y1) and P2 = (X2, Y2):
P1 + P2 = (X1, Y1) + (X2, Y2) = (X1 + X2, Y1 + Y2)

Given a number C and a point P = (X,Y)
C*P = C*(X,Y) = (C*X,C*Y)


In GS, you can represent a point as an array with two numbers in it. Like {1,2} or {3.5,10}.




So, let's investigate the problem at hand:

This is how I describe the function Beizer in terms of what it wants and what it gives back: Given 3 points and 1 number, I'll give you back a point.

So, translated into GS2...
PHP Code:
function beizer(temp.atemp.btemp.ctemp.dtemp.t) {
  return 
somePointHere;

Unfortunately, GS isn't expressive enough to let us show that a, b, c, and d are points and t is a number, so we'll just have to remember that they are instead.


The formula for a cubic beizer curve is this:
B(t) = (1 - t)^3 * a + (1 - t)^2 * 3 * t * b + (1 - t) * 3 * t^2 * c + t^3 * d

This almost translates directly into GS, but we need to take into account the fact that we are working with points (a, b, c, and d), and numbers (t), instead of only numbers.

To get the coordinates of the points out of the array, for example with a, do this: a[0] would give you the first coordinate, and a[1] would give you the second.

So (1 - t)^3 * a in the original formula is actually {(1 -t)^3 * a[0], (1 - t)^3 * a[1]} in GS2.

Thankfully, GS already has functions which do these operations for us:
vectorscale(point, number) and vectoradd(point, point).

So (1 - t)^3 * a in the original formula can be written as vectorscale(a, (1-t)^3).

Now it is just a matter of putting this all together...
PHP Code:
function beizer(temp.atemp.btemp.ctemp.dtemp.t) {
  
temp.part1 vectorscale(temp.a, (temp.t)^3);
  
temp.part2 vectorscale(temp.b, (temp.t)^temp.t);
  
temp.part3 vectorscale(temp.c, (temp.t) * temp.t^2);
  
temp.part4 vectorscale(temp.dtemp.t^3);
  return 
vectoradd(temp.part1vectoradd(temp.part2vectoradd(temp.part3temp.part4)));

You call it like this:
PHP Code:
function onWeaponFired() {
  
player.chat this.beizer({1,2,0}, {2,3,0}, {4,5,0}, {5,6,0}, 0.5);

Note: the vector functions require 3D points, but it doesn't matter since you just make the third coordinate 0. However, this has the nice benefit of working in three dimensions if you need it.

The alternative to the vector functions is to write out the formula twice for each coordinate of the point, but that means you'll have duplicate code which gets annoying to maintain.

Edit: Okay this post took me forever to write, fowlplay beat me to it . Hopefully this is still useful since it shows another way of writing the code.

Last edited by WhiteDragon; 01-19-2011 at 02:03 AM..
Reply With Quote
  #4  
Old 01-19-2011, 03:12 AM
dabblercody dabblercody is offline
Tech Assistant
dabblercody's Avatar
Join Date: May 2006
Location: Florida
Posts: 22
dabblercody is on a distinguished road
Thanks a ton. Yeah I had the thought in the back of my head saying use arrays but this has been a good experience. I also have another question I heard some type or form of Bezier Curves can be used in ways of Interpolation which I got the idea from looking at Downsider's Interpolation script. I can't really jot out what it would look like in GS form. Any ideas?
__________________
Dabbler

"Our work is the presentation of our capabilities."
- Goethe, Johann Wolfgang Von
Reply With Quote
  #5  
Old 01-19-2011, 05:50 AM
WhiteDragon WhiteDragon is offline
Banned
Join Date: Feb 2007
Posts: 1,002
WhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to behold
You can't really plug-and-play Bezier curves into downsider's interpolation script.

When you draw a Bezier curve through a set of control points, it does not need to touch the all control points, only the start and end points. For interpolation, this is obviously useless because you won't even be hitting the points that you know the object has been at.

However, it is possible to calculate control points from a set of points that you want the Bezier curve to pass through. But this takes a good amount of math, and is also more difficult to get running efficiently than simple interpolation like linear or cosine.
Reply With Quote
  #6  
Old 01-20-2011, 02:28 AM
dabblercody dabblercody is offline
Tech Assistant
dabblercody's Avatar
Join Date: May 2006
Location: Florida
Posts: 22
dabblercody is on a distinguished road
Im assuming your referring to Linear Bezier Spline, which is obtained by linear interpolation between two control points P0 , P1?
__________________
Dabbler

"Our work is the presentation of our capabilities."
- Goethe, Johann Wolfgang Von
Reply With Quote
  #7  
Old 01-20-2011, 02:47 AM
WhiteDragon WhiteDragon is offline
Banned
Join Date: Feb 2007
Posts: 1,002
WhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to behold
This idea is called "spline interpolation", where you use piecewise polynomials to interpolation. Normally this is done with basis functions which results in B-splines. But it is also possible to use Bernstein polynomials which results in Bezier splines.

Linear spline interpolation gets you nothing more than normal linear interpolation, you need to go into quadratic and cubic spline interpolation to see the differences.
Reply With Quote
  #8  
Old 01-20-2011, 03:24 AM
dabblercody dabblercody is offline
Tech Assistant
dabblercody's Avatar
Join Date: May 2006
Location: Florida
Posts: 22
dabblercody is on a distinguished road
Alright I'll take a look into it, thanks.
__________________
Dabbler

"Our work is the presentation of our capabilities."
- Goethe, Johann Wolfgang Von
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 10:56 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.