Showing posts with label C. Show all posts

Simple basic spiral code implementation 2 with tolerance 0.1

Simple basic spiral code implementation 2 with tolerance 0.1

This is the sequel of the previous code implementation of spiral, that time I made a very simple archimedean spiral with the same step over. But sometime, we want more than a step over, a distance between each point of a spiral (tolerance).

Here is my code implementation in c.

 /**********************************************************************  
  *  
  *  
  *    @par    Copyright(C)  
  *    2018     Tokyo University of Agriculture, Saville Lab.  
  *    All rights reserved.  
  *  
  *    @par    History:  
  *    - 2018/07/15    Saville Ramadhona  
  *        - first code.  
  *  
  ***********************************************************************/  
 /*  
  * Program to make spiral curve and put the point on spiral  
  * based on tollerance (point distance).  
  * Not based on parameter of spiral curve.  
  * eg. When tollerance is o.1, distance between adjacent points on spiral   
  * must not exceed the tollerance.   
  *  
  */  
   
   
 #include<stdio.h>  
 #include<math.h>  
   
 #define M_PI 3.14159265358979323846  
   
 /**  
  *    function to evaluate/compute point on spiral  
  *  
  *    @param[in]    param    spiral parameter  
  *    @param[in]    theta    angle in computed point (radians)  
  *    @param[out]    pt        array coordinate of computed point on spiral (x,y)   
  *    @return                radius of center point of spiral to computed point  
  */  
 double evalSpiralpt(double param, double theta, double pt[2])  
 {  
     double r = param*theta;  
     pt[0] = r * cos(theta);  
     pt[1] = r * sin(theta);  
     return r;  
 }  
   
 /**  
  *    function to check distance square between adjacent points  
  *    we do not use sqrt to make computation faster  
  *  
  *    @param[in]    point        newly computed point on spiral   
  *    @param[in]    prevpoint    previously computed point on spiral   
  *    @return                    distance square obetween adjacent points  
  */  
 double checkDistpt2(double point[2], double prevpoint[2])  
 {  
     return (point[0]-prevpoint[0])*(point[0]-prevpoint[0])   
             + (point[1]-prevpoint[1])*(point[1]-prevpoint[1]);  
 }  
   
 //spiral definition r = a + bθ  
 void main()  
 {  
     //remove file if exist  
   int status;  
   status = remove("C:\\Users\\BA17655\\Documents\\spiral.csv");  
     
   //prepare csv file to see the computation result  
   FILE *fp;  
   fp = fopen("C:\\Users\\BA17655\\Documents\\spiral.csv", "a");  
   
   fprintf(fp, "rad, theta, r, x, y, d\n");  
   
     double pi_2 = 2* M_PI;  
     int numTurns = 5;                                      //automatically determine by detecting outer edge, later!  
     double stepover = 0.1;                                 //tool path stepover (USER INPUT)  
     double distanceBetweenTurns = stepover * (1 / (pi_2)); //b  
     double theta = 0.0;                                    //starting angle  
     double offset = 0.0;                                   //a (offset of starting point)  
   
     /*  
     double pointsPerTurn = 20; //to be modified  
     for(int i=0; i<(pointsPerTurn*numTurns+1); i++)  
     {  
         double r = offset + (distanceBetweenTurns*theta);  
         double point[2];  
         point[0] = r * cos(theta);  
         point[1] = r * sin(theta);  
   
         printf("%f %f %f %f \n", theta*(180.0/M_PI), r, point[0], point[1]);  
         theta += pi_2 / pointsPerTurn;  
     }  
     */  
   
     double dist_thres2 = 0.01;          //distance threshold(control point tollerance - USER INPUT)  
     int cnt = 0;  
     double point[2];                    //x, y coordinate control point on spiral  
     double prevpoint[2];  
     double prevtheta;  
     double degree;  
     double sizelimit = numTurns * 360.0; //to sizelimit the size of spiral  
     do  
     {  
         //evaluate point in spiral   
         double r = evalSpiralpt(distanceBetweenTurns, theta, point);  
   
         if( cnt < 1 )  
         {  
             fprintf(fp, "%f, %f, %f, %f, %f\n", theta, theta*(180.0/M_PI), r, point[0], point[1]);  
             theta += pi_2 * dist_thres2;  
         }  
         if( cnt > 0 )  
         {  
             //check distance of control point  
             double dist2 = checkDistpt2(point, prevpoint);  
   
             //check if point distance exceed tolerance  
             if( dist2 > dist_thres2 )   
             { //if exeec tollerance, compute new control point  
                 do   
                 {  
                     //make the new point to be located in the middle of previous and current point  
                     theta = (theta + prevtheta) * 0.5;  
                     r = evalSpiralpt(distanceBetweenTurns, theta, point);  
                     dist2 = checkDistpt2(point, prevpoint);  
   
                     //when above is not enough, do it one more time!  
                     if( dist2 > dist_thres2 )  
                     {  
                         theta = (theta + prevtheta) * 0.5;  
                         r = evalSpiralpt(distanceBetweenTurns, theta, point);  
                         dist2 = checkDistpt2(point, prevpoint);  
                     }  
                 }while( dist2 > dist_thres2 ); //when point distance lies under the tollerance, exit loop  
             }  
   
             fprintf(fp, "%f, %f, %f, %f, %f, %f\n", theta, theta*(180.0/M_PI), r, point[0], point[1], dist2);  
             prevtheta = theta;  
             theta += pi_2 * dist_thres2;  
         }          
           
         cnt++;  
                   
         prevpoint[0] = point[0];  
         prevpoint[1] = point[1];  
         degree = theta*(180.0/M_PI);  
   
     }while( degree <= sizelimit );  
   
 }  

After running the code, it will print out the angle (radian), angle (degree), r of each point(interpreted as 1/curvature), x, y coordinate of each point, and the distance of each point.
The plotted spiral from the code in excel is as shown below.

Pretty simple right!



spiral 2

Simple basic archimedean spiral code implementation

Recently, I have an interest to draw spiral with the same step over (distance between one spiral cycle).
Actually, it is pretty simple to draw basic archimedean spiral. The mathematical formula for archimedean spiral is
r = a + bθ,
with r is radius at each spiral point, a is offset of starting point of spiral and b is the coefficient of angle θ. Then for the point at spiral, it is the same like parametric circle
x coordinate = r * cos(theta) and
y coordinate = r * sin(theta).
Here is my code implementation of simple basic archimedean spiral.

 #include<stdio.h>  
 #include<math.h>  
   
 #define M_PI 3.14159265358979323846  
   
 //spiral definition r = a + bθ  
 void main()  
 {  
     int numTurns = 5;                                      //number of spiral cycle 
     double stepover = 0.1;                                 //distance between one spiral cycle   
     double distanceBetweenTurns = stepover * (1/(2*M_PI)); //b 2*PI is 360deg  
     double theta = 0.0;                                    //starting angle, all in radian  
     double offset = 0.0;                                   //a (offset of starting point)  
       
     double pointsPerTurn = 20; //number of point in each spiral cycle  
     printf("rad, theta, r, x, y\n");  
     for(int i=0; i<(pointsPerTurn*numTurns+1); i++)  
     {  
         double r = offset + (distanceBetweenTurns*theta);  
         double point[2];  
         point[0] = r * cos(theta);  
         point[1] = r * sin(theta);  
   
         //print out the point to be plotted   
         printf("%f, %f, %f, %f, %f\n",theta, theta*(180.0/M_PI), r, point[0], point[1]);  
         theta += 2*M_PI / pointsPerTurn;  
     }      
 }  

After running the code, it will print out the angle (radian), angle (degree), r of each point(interpreted as 1/curvature), x and y coordinate of each point.
The plotted spiral from the code in excel is as shown bellow.
Pretty simple right!




*NB bonus:This kind of spiral are used for making spiral toolpath. Usually, projected onto target surface.
But, of course we have to modify the point at the spiral, because distance between each point gets larger and larger as the spiral grow. For this I am going to save the code for the next post.

1. playing with string manipulation, 2. function to sort dynamically alocated string array in visual c++

 #include "stdafx.h"  
 #include <string.h>     //header for string manipulation  
 #include <cstdlib>     //header for malloc  
   
 #define COL 300  
 bool sortStr(char(*str)[COL], int n)  
 {     //function to sort string array   
      if( str == NULL )     return false;  
      char tmp[COL];  
      for(int i=0; i<n-1; ++i)  
      {  
           for(int j=i+1; j<n; ++j)  
           {  
                if( strcmp(str[i], str[j]) > 0 )  
                {                      
                     strcpy_s(tmp, str[i]);  
                     strcpy_s(str[i], str[j]);  
                     strcpy_s(str[j], tmp);  
                }  
           }  
      }  
      return true;  
 }  
 int _tmain(int argc, _TCHAR* argv[])  
 {  
      int ncp = 4;                     //for string array  
      //dynamic allocation of string array
      char(*str0)[COL] = (char(*)[COL])malloc(sizeof(char)*ncp*COL);  
   
      int id0 = 9, id1 = 12;       
      strcpy_s(str0[0], "s");          //input your string  
      strcpy_s(str0[1], "e");  
      char tmp[COL];  
      sprintf_s(tmp, "%d", id1);      //input int value (id1) into string tmp  
      strcat_s(str0[0], tmp);         //concatenate multiple strings into str[0]  
      sprintf_s(tmp, "%d", id0);  
      strcat_s(str0[1], tmp);  
      strcpy_s(str0[2], "e1");  
      strcpy_s(str0[3], "s2");       
      for(int i=0; i<ncp; ++i)  
           printf("str0[%d]:%s\n", i, str0[i]);  
      printf("--\n");  
             
      char(*str1)[COL] = (char(*)[COL])malloc(sizeof(char)*ncp*COL);  
      strcpy_s(str1[0], "e9");  
      strcpy_s(str1[1], "s12");  
      strcpy_s(str1[2], "e1");  
      strcpy_s(str1[3], "s3");  
   
      for(int i=0; i<ncp; ++i)  
           printf("str1[%d]:%s\n", i, str1[i]);  
   
      printf("\n=======compare=======\n");  
      printf("====before sorting===\n");  
      for(int i=0; i<ncp; ++i)  
      {  
           int res = strcmp(str0[i], str1[i]);     //compare 2 strings value based on ASCII  
           printf("str[%d]: %d\n", i, res);  
      }  
   
      printf("\n=======sort=======\n");  
        
      if( sortStr(str0, ncp) == true )  
      {  
           for(int i=0; i<ncp; ++i)  
                printf("str0[%d]:%s\n", i, str0[i]);  
      }  
             
      printf("--\n");  
        
      if( sortStr(str1, ncp) == true )  
      {  
           for(int i=0; i<ncp; ++i)  
                printf("str0[%d]:%s\n", i, str1[i]);  
      }       
   
      printf("\n=======compare=======\n");  
      printf("====after sorting====\n");  
      for(int i=0; i<ncp; ++i)  
      {  
           int res = strcmp(str0[i], str1[i]);  
           printf("str[%d]: %d\n", i, res);  
      }  
 } 
result
 
str0[0]:s12
str0[1]:e9
str0[2]:e1
str0[3]:s2
--
str1[0]:e9
str1[1]:s12
str1[2]:e1
str1[3]:s3

=======compare=======
====before sorting===
str[0]: 1
str[1]: -1
str[2]: 0
str[3]: -1

=======sort=======
str0[0]:e1
str0[1]:e9
str0[2]:s12
str0[3]:s2
--
str0[0]:e1
str0[1]:e9
str0[2]:s12
str0[3]:s3

=======compare=======
====after sorting====
str[0]: 0
str[1]: 0
str[2]: 0
str[3]: -1

centripetal parametrization for curve fitting or interpolation

very useful to compute parameter for curve fitting or interpolation
the detail explanation is written here


and here is the code for three dimensional parametric curve


 void GetCentripetal_Param(  
       int ncp,                                                  //number of control point  
       double point[][3],                                        //control points of curve  
       double t[]                                                //array of t parameter (output) 
       )  
 {  
      double *dcp = (double*)malloc(sizeof(double) * (ncp-1));   //CP0-CP1, CP2-CP1, ..., CP[ncp-1][ncp]  
      double *sum = (double*)malloc(sizeof(double) * ncp);  
             
      int i, j;  
      double dcptotal = 0.0;  
      for(i=0; i<ncp-1; i++)  
           dcp[i] = 0.0;  
        
      sum[0] = 0.0;  
      for(i=0; i<ncp-1; i++)  
      {  
        for(j=0; j<3; j++)  
          dcp[i] += (point[i+1][j]-point[i][j]) * (point[i+1][j]-point[i][j]);        
       
        dcp[i] = sqrt(sqrt(dcp[i]));  
        dcptotal += dcp[i];  
        sum[i+1] = dcptotal;  
      }  
      sum[0] = 0.0;  
      double inv_dcptotal = 1 / dcptotal;  
      for(i=0; i<ncp; i++)  
         t[i] = (sum[i] * inv_dcptotal);  
        
      if(dcp) free(dcp);  
      if(sum) free(sum);  
 }     

compute derivative coefficient of n-th degree polynomial equation

 #include <stdio.h>  
 #define ELE 4  
   
 int main()  
 {  
  int i;  
  int g = 3; //degree  
  double c[ELE][3] = {{1, 5, 9},   
                      {2, 6, 10},  
                      {3, 7, 11},  
                      {4, 8, 12}};   
    
  //ELE coefficient of parametric equation  
  //eg ELE == 0 4x^3 + 3x^2 + 2x + 1 2d element of array is x, y, z  
    
  for(int i=0; i<ELE; i++)  
  {  
   for(int j=0; j<3; j++)  
     printf("%.1f ", c[i][j]);  
   printf("\n");  
  }  
  printf("\n--\n");  
   
  //derivative  
  int n = 2; //n-th derivative   
  for(int drv=1; drv<=n; drv++)  
   for(i=g; i>=0; i--)  
     for(int axs=0; axs<3; axs++) //if we want the derivative not be 3 dimensional parametric equation delete this loop  
      c[i][axs]=c[i][axs]*(i-(drv-1));  
  //derivative  
   
  for(int i=0; i<ELE; i++)  
  {  
   for(int j=0; j<3; j++)  
     printf("%.1f ", c[i][j]);  
   printf("\n");  
  }  
   

2d dynamic array with known number of column element

how to make dynamic array with known number of column element
for example for a 3d coordinate.

suppose i need to make 2d dynamic array for a 3d coordinate, because the element of 3d coordinate is x, y, z so the number column is 3.
let's say i need to have
double point[some_number][3];
and that number is suppose unknown until we read the file, lets say ptscount.

one simple way to allocate the dynamic 2d array is as follow. 


double (*point)[3] = (double (*)[3])malloc(sizeof(double) * ptscount*3);

brief explanation
- double (*point)[3]: double variable of  "point" that has 3 array element, this will make point[ptscount][3]

- (double (*)[3]): casting to double of pointer that has 3 array element

- malloc(sizeof(double) * ptscount*3): memory allocation for (the size of double variable) times(×) (ptscount (number or row of the array) with 3 column)

after using it you have to free the memory
free (point);

use malloc for struct

 #include <stdio.h>  
 #include <stdlib.h>  
   
 struct Healdirect  
 {  
    double m_tors;  
    double curvedir[3];  
 };  
   
 void showme(struct Healdirect *healdeci)  
 {     
    struct Healdirect test;  
   
    test.m_tors = healdeci->m_tors;  
    test.curvedir[0] = healdeci->curvedir[0];  
    test.curvedir[1] = healdeci->curvedir[1];  
    test.curvedir[2] = healdeci->curvedir[2];  
   
    printf("torsion: %.2f \n", test.m_tors);  
    printf("curvature direction: ");  
    for(int i=0; i<3; i++)  
       printf("%.2f ", test.curvedir[i]);  
    printf("\n");  
 }  
   
 void main()  
 {  
    //example of struct using pointer and malloc  
    struct Healdirect *hd = malloc(sizeof(hd));  
      
    //sample data   
    hd->m_tors = 0.24;  
   hd->curvedir[0] = 0.99;  
   hd->curvedir[1] = 0.88;  
   hd->curvedir[2] = 0.77;  
   
   //show sample data after the memory is filled  
   showme(hd);  
   
   //free the memory  
   if(hd) free(hd);  
 }  
   

dynimcally allocated array 2

 #include <stdio.h>  
 #include <stdlib.h>  
   
 void main()  
 {  
    double *ary;   //will be your dynamic 1d array  
    int num;       //your array element  
   
    //input your number of array element  
    printf("num: ");  
    scanf("%d", &num);  
   
    //syntax: number of block address times byte needed (sizeof) for double variable  
    ary = malloc(num * sizeof(double));     
   
    //fill the array (can be changed to any number) and display them  
    for(int i=0; i<num; i++)  
    {  
       ary[i] = i * i * 2.8;  
       printf("%.2f\n", ary[i]);  
    }  
   
    //must free the memory allocation to not make memory leak  
    if(ary) free(ary);  
 }  
   

dynamically allocated 2d array using an array of pointers

 #include <stdio.h>   
 #include <stdlib.h>   
     
  void main()   
  {   
    int row = 5, col = 3;   
    int i, j;   
    double *ar[row]; //will be your 2d array   
   
    for(i=0; i<row; i++)  //make it into 2d array
         ar[i] = malloc(sizeof(int)*col);  //get the column number of array
   
    for(i=0; i<row; i++)  
    {  
         for(j=0; j<col; j++)  
         {  
              ar[i][j] = (i + j) * 1.0;  //filling the array element
         }  
    }  
     
    for(i=0; i<row; i++)  
    {  
         for(j=0; j<col; j++)  
         {  
          printf("[%d][%d]=%.2f ", i, j, ar[i][j]);   //print the array after filling it
         }  
         printf("\n");  
    }  
   
    //must free the memorry allocation after using it  
    for(i=0; i<row; i++)  
         free(ar[i]);      
  } 
result:
[0][0]=0.00 [0][1]=1.00 [0][2]=2.00
[1][0]=1.00 [1][1]=2.00 [1][2]=3.00
[2][0]=2.00 [2][1]=3.00 [2][2]=4.00
[3][0]=3.00 [3][1]=4.00 [3][2]=5.00
[4][0]=4.00 [4][1]=5.00 [4][2]=6.00

dynamically allocated array

 #include <stdio.h>  
 #include <stdlib.h>  
   
 void main()  
 {  
     double *ar; //will be your array  
     double elem[] = {0.1, 0.2 ,0.3 ,0.4 ,0.5};   
     int num = 5, i;  
   
     printf("array number: %d\n", num);  
     for(i=0; i<num; i++)  
         printf("[%d]:%.2f\n", i, elem[i]);  
   
     printf("lets double it and put in your new array using malloc\n");  
     printf("--\n");  
   
     ar = malloc(sizeof(double)*num); //allocate the memory for your array  
   
     for(i=0; i<num; i++){  
       *(ar+i) = elem[i] * 2;  
     }  
   
     for(i=0; i<num; i++)   
         printf("array[%d]=%.2f\n", i, ar[i]);  
   
 free(ar); //must free the memorry allocation after using it  
 } 
 
result:
-------------- 
 array number: 5
[0]:0.10
[1]:0.20
[2]:0.30
[3]:0.40
[4]:0.50
lets double it and put in your new array using malloc
--
array[0]=0.20
array[1]=0.40
array[2]=0.60
array[3]=0.80
array[4]=1.00 

binomial coefficient c code

 #include<stdio.h>  
   
 //binomial coefficient function  
 double Ni(  
         int deg,    //degree   
         int b       //for binomial  
         )  
 {  
     if( deg < 0 )  
         return 0.0;  
     else if ( deg == 0 )  
         return 1.0;  
     else{  
         double temp = 1.0;  
         for(int i=1; i<=b;i++ ){  
             temp = temp* (double)(deg-i+1)/i;  
             printf("%f\n", temp);  
         }  
         return temp;  
     }  
 }  
   
   
 void main ()  
 {  
     int a=10, b=3;  
     double bin;  
     bin = Ni(a, b);  
     printf("\n=============\n");  
     printf("%f\n", bin);  
 }  

comparison of secant and bisection method

   
 #include<stdio.h>  
 #include<math.h>  
 #include<time.h>  
   
 //example of function f(t), you can make any function you like  
 float f(float t)  
 {  
   return(((48.2291-30.6208*t-43) * (48.2291-30.6208*t-43)) + 35*t - 25.0);   
 }  
   
 void main()  
 {  
     
   float a = 0.1, b = 0.3, c = 0, e = 7.5e-3;  
   //a, b interval  
   //e error  
   
   int count = 1, n = 50; //n=maximum iteration  
     
   //  
   //secant  
   //  
   clock_t begin = clock();  
   do  
   {      
     c = (a*f(b) - b*f(a)) / (f(b) - f(a));  
     //c = b - (f(b)*(b-a) / (f(b) - f(a)));  
     a=b;  
     b=c;  
     printf("i No-%d  t=%f  d=%f\n",count,c, f(c));  
     count++;  
     if(count==n) break;  
   } while(fabs(f(c))&gt;e);  
   
   clock_t end = clock();  
   double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;  
   printf("time:%f", time_spent);  
   
   printf("\nThe required solution is %f\n",c);  
   printf("d = %f\n", f(c) + 25);  
   
   //  
   //bisection  
   //  
   double fa, fb, fc;  
   a = 0.1; b = 0.3; c = 0; e = 7.5e-3;  
   count = 1;  
   clock_t begin2 = clock();  
   do{  
     c = (a+b)/2;  
     fa = f(a);  
     fb = f(b);  
     fc = f(c);  
   
     if(fa*fc &lt; 0){  
       b = c;  
     }  
     else{  
       a = c;  
     }  
     printf("i No-%d  t=%f  d=%f\n", count, c, fc);  
     count++;  
     if(count==n) break;  
   } while(fabs(fc)&gt;e);  
   
   clock_t end2 = clock();  
   double time_spent2 = (double)(end2 - begin2) / CLOCKS_PER_SEC;  
   printf("time:%f", time_spent2);  
   
   printf("\nThe required solution is %f\n",c);  
   printf("d = %f\n", fc + 25);  
   
    
 }  

dynamic 2d array using double data type

 #include <stdio.h>  
 #include <iostream>  
   
   
 int main() {  
  // dimensions  
  int N = 74;  
  int M = 3;  
   
  int i, j;  
    
  // dynamic allocation  
  double** ary = new double*[N];   //2d array  
  for(i = 0; i < N; ++i)         //↑  
    ary[i] = new double[M];      //1d array  
    
  for(i=0; i<N; i++){  
       for(j=0; j<M; j++){  
          ary[i][j] = i+j;  
          printf("point[%d][%d] = %.2f \n", i, j, ary[i][j]);  
       }  
    }  
    
  // free  
  for(i = 0; i < N; ++i)  
   delete [] ary[i];  
  delete [] ary;  
    
  return 0;  
 }  

//reffer to [http: codeformatter.blogspot.jp]

passing and returning array in c language

#include                                         //standard library
#include                                        //standard mathematical library

//first derivative function
static double* GetDerivative(double t, double A[], double B[], double C[])       
                                                              //the function must be pointer double*
                                                              //for returning array

{
    //P・(t) = 3At^2 + 2Bt + C
    static double Pdot[3] = {0};                      //must be static
   
    Pdot[0] = 3*A[0]*t*t + 2*B[0]*t + C[0];
    Pdot[1] = 3*A[1]*t*t + 2*B[1]*t + C[1];
    Pdot[2] = 3*A[2]*t*t + 2*B[2]*t + C[2];
   
    return Pdot;                                       //return the array
}
//first derivative function

int main ()
{
    //P(t) = At3 + Bt2 + Ct + D
    ////P・(t) = 3At^2 + 2Bt + C
    double *derivative = 0;                        //must be pointer double *
                                                          //because the function is a pointer as well

    //double t[4] = {0.0, 0.25, 0.5, 0.75};
    double t[1] = {1};
    double A[] = {1, 2, 3};
    double B[] = {4, 6, 6};
    double C[] = {7, 8, 9};
    double D[] = {10, 11, 12};

    derivative = GetDerivative(t[0], A, B, C);    //put the return function to derivative
                                                              //plus make it as an array
                                                              //do not add [] even if it is array,
                                                              // unless you want to point the specific
                                                              // address of the array like t[0]
   
    printf("%ft2 + %ft + %f \n", derivative[0], derivative[1], derivative[2]);

    return 0;
}

//output 18.000000t2 + 26.000000t + 30.000000