Jump to content

Help with C conversion


Recommended Posts

Hey,

Im working on some 3D spline stuff and wanted to convert a nice function i found written in C (i think)

http://www.flong.com/texts/code/shapers_bez/

It seem like i converted the "cubicBezierNearlyThroughTwoPoints" function correctly, but the "cubicBezier" function is giving me some problems.

float cubicBezier (float x, float a, float b, float c, float d){

  float y0a = 0.00; // initial y
  float x0a = 0.00; // initial x 
  float y1a = b;    // 1st influence y   
  float x1a = a;    // 1st influence x 
  float y2a = d;    // 2nd influence y
  float x2a = c;    // 2nd influence x
  float y3a = 1.00; // final y 
  float x3a = 1.00; // final x 

  float A =   x3a - 3*x2a + 3*x1a - x0a;
  float B = 3*x2a - 6*x1a + 3*x0a;
  float C = 3*x1a - 3*x0a;   
  float D =   x0a;

  float E =   y3a - 3*y2a + 3*y1a - y0a;    
  float F = 3*y2a - 6*y1a + 3*y0a;             
  float G = 3*y1a - 3*y0a;             
  float H =   y0a;

  // Solve for t given x (using Newton-Raphelson), then solve for y given t.
  // Assume for the first guess that t = x.
  float currentt = x;
  int nRefinementIterations = 5;
  for (int i=0; i < nRefinementIterations; i++){
    float currentx = xFromT (currentt, A,B,C,D); 
    float currentslope = slopeFromT (currentt, A,B,C);
    currentt -= (currentx - x)*(currentslope);
    currentt = constrain(currentt, 0,1);
  } 

  float y = yFromT (currentt,  E,F,G,H);
  return y;
}

// Helper functions:
float slopeFromT (float t, float A, float B, float C){
  float dtdx = 1.0/(3.0*A*t*t + 2.0*B*t + C); 
  return dtdx;
}

float xFromT (float t, float A, float B, float C, float D){
  float x = A*(t*t*t) + B*(t*t) + C*t + D;
  return x;
}

float yFromT (float t, float E, float F, float G, float H){
  float y = E*(t*t*t) + F*(t*t) + G*t + H;
  return y;
}

I don't quite know how to translate this: "for (int i=0; i < nRefinementIterations; i++){"

Also "constrain(currentt, 0,1)" since AutoIT does not have a such funciton, i would presume that it was like "keep variable between 0,1" but not sure.

Anyway, here is what i got so far:

#include <Math.au3>
func cubicBezier($x, $a, $b, $c, $d)

dim $y0a = 0.00; // initial y
dim $x0a = 0.00; // initial x 
dim $y1a = $b;    // 1st influence y   
dim $x1a = $a;    // 1st influence x 
dim $y2a = $d;    // 2nd influence y
dim $x2a = $c;    // 2nd influence x
dim $y3a = 1.00; // final y 
dim $x3a = 1.00; // final x 

$A =    $x3a - 3*$x2a + 3*$x1a - $x0a;
$B =    3*$x2a - 6*$x1a + 3*$x0a;
$C =    3*$x1a - 3*$x0a;   
$D =    $x0a;

$E =   $y3a - 3*$y2a + 3*$y1a - $y0a;    
$F = 3*$y2a - 6*$y1a + 3*$y0a;             
$G = 3*$y1a - 3*$y0a;             
$H =   $y0a;




;// Solve for t given x (using Newton-Raphelson), then solve for y given t.
;  // Assume for the first guess that t = x.
$currentt = $x;
  $nRefinementIterations = 5;
  for $i=0 ;?????????????????????????????????????????????????????
    $currentx = xFromT ($currentt, $A,$B,$C,$D); 
    $currentslope = slopeFromT ($currentt, $A,$B,$C);
    $currentt -= ($currentx - $x)*($currentslope);
    ;$currentt = constrain($currentt, 0,1);

  $y = yFromT ($currentt,  $E,$F,$G,$H);
  ConsoleWrite( $y &@crlf)
  return $y
Next
EndFunc

;// Helper functions:
func slopeFromT ($_t, $_A, $_B, $_C)
    $dtdx = 1.0/(3.0*$_A*$_t*$_t + 2.0*$_B*$_t + $_C); 
return $dtdx;
EndFunc

func xFromT ($_t, $_A, $_B, $_C, $_D)
  $_x = $_A*($_t*$_t*$_t) + $_B*($_t*$_t) + $_C*$_t + $_D;
  return $_x;
EndFunc

func yFromT ($_t, $_E, $_F, $_G, $_H)
  $_y = $_E*($_t*$_t*$_t) + $_F*($_t*$_t) + $_G*$_t + $_H;
  return $_y;
EndFunc


func cubicBezierNearlyThroughTwoPoints( $x, $a, $b, $c, $d)
  $y = 0;
  $epsilon = 0.00001;
  $min_param_a = 0.0 + $epsilon;
  $max_param_a = 1.0 - $epsilon;
  $min_param_b = 0.0 + $epsilon;
  $max_param_b = 1.0 - $epsilon;
  $a = _max($min_param_a, _min($max_param_a, $a));
  $b = _max($min_param_b, _min($max_param_b, $b));

  $x0 = 0;  
  $y0 = 0;
  $x4 = $a;  
  $y4 = $b;
  $x5 = $c;  
  $y5 = $d;
  $x3 = 1;  
  $y3 = 1;
  dim $x1,$y1,$x2,$y2; // to be solved.

 ; // arbitrary but reasonable 
 ; // t-values for interior control points
  $t1 = 0.3;
  $t2 = 0.7;

  $B0t1 = B0($t1);
  $B1t1 = B1($t1);
  $B2t1 = B2($t1);
  $B3t1 = B3($t1);
  $B0t2 = B0($t2);
  $B1t2 = B1($t2);
  $B2t2 = B2($t2);
  $B3t2 = B3($t2);

  $ccx = $x4 - $x0*$B0t1 - $x3*$B3t1;
  $ccy = $y4 - $y0*$B0t1 - $y3*$B3t1;
  $ffx = $x5 - $x0*$B0t2 - $x3*$B3t2;
  $ffy = $y5 - $y0*$B0t2 - $y3*$B3t2;

  $x2 = ($ccx - ($ffx*$B1t1)/$B1t2) / ($B2t1 - ($B1t1*$B2t2)/$B1t2);
  $y2 = ($ccy - ($ffy*$B1t1)/$B1t2) / ($B2t1 - ($B1t1*$B2t2)/$B1t2);
  $x1 = ($ccx - $x2*$B2t1) / $B1t1;
  $y1 = ($ccy - $y2*$B2t1) / $B1t1;

  $x1 = _max(0+$epsilon, _min(1-$epsilon, $x1));
  $x2 = _max(0+$epsilon, _min(1-$epsilon, $x2));
ConsoleWrite($x1 &@crlf)
ConsoleWrite($x2 &@crlf)
 ; // Note that this function also requires cubicBezier()!
  ;y = cubicBezier (x, x1,y1, x2,y2);
  ;y = max(0, min(1, y));
 ; return y;
;}
EndFunc
;// Helper functions. 
func B0 ($t)
  return (1-$t)*(1-$t)*(1-$t);
EndFunc

func B1 ($t)
  return  3*$t* (1-$t)*(1-$t);
EndFunc

func B2 ($t)
  return 3*$t*$t* (1-$t);
EndFunc

func B3 ($t)
  return $t*$t*$t;
EndFunc

func  findx ($t, $x0, $x1, $x2, $x3)
  return $x0*B0($t) + $x1*B1($t) + $x2*B2($t) + $x3*B3($t);
EndFunc

func  findy ($t, $y0, $y1, $y2, $y3)
  return $y0*B0($t) + $y1*B1($t) + $y2*B2($t) + $y3*B3($t);
EndFunc

[center][u]WoW Machinima Tool[/u] (Tool for Machinima Artists) [/center]

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...