void getRotationMatrixFromOrientation(double out[9], double orientation[3]) { double xM[9]; double yM[9]; double zM[9]; double sinX = sin(orientation[1]); double cosX = cos(orientation[1]); double sinY = sin(orientation[2]); double cosY = cos(orientation[2]); double sinZ = sin(orientation[0]); double cosZ = cos(orientation[0]); // rotation about x-axis (pitch) xM[0] = 1.0f; xM[1] = 0.0f; xM[2] = 0.0f; xM[3] = 0.0f; xM[4] = cosX; xM[5] = sinX; xM[6] = 0.0f; xM[7] = -sinX; xM[8] = cosX; // rotation about y-axis (roll) yM[0] = cosY; yM[1] = 0.0f; yM[2] = sinY; yM[3] = 0.0f; yM[4] = 1.0f; yM[5] = 0.0f; yM[6] = -sinY; yM[7] = 0.0f; yM[8] = cosY; // rotation about z-axis (azimuth) zM[0] = cosZ; zM[1] = sinZ; zM[2] = 0.0f; zM[3] = -sinZ; zM[4] = cosZ; zM[5] = 0.0f; zM[6] = 0.0f; zM[7] = 0.0f; zM[8] = 1.0f; // rotation order is y, x, z (roll, pitch, azimuth) matrixMultiplication(out, xM, yM); matrixMultiplication(out, zM, out); }
/** From http://www.thousand-thoughts.com/2012/03/android-sensor-fusion-tutorial/2/ * Should be optimized ... */ void getRotationMatrixFromOrientation(float* orientation, float* result) { float xM[9]; float yM[9]; float zM[9]; float sinX = (float)qSin(orientation[1]); float cosX = (float)qCos(orientation[1]); float sinY = (float)qSin(orientation[2]); float cosY = (float)qCos(orientation[2]); float sinZ = (float)qSin(orientation[0]); float cosZ = (float)qCos(orientation[0]); // rotation about x-axis (pitch) xM[0] = 1.0f; xM[1] = 0.0f; xM[2] = 0.0f; xM[3] = 0.0f; xM[4] = cosX; xM[5] = sinX; xM[6] = 0.0f; xM[7] = -sinX; xM[8] = cosX; // rotation about y-axis (roll) yM[0] = cosY; yM[1] = 0.0f; yM[2] = sinY; yM[3] = 0.0f; yM[4] = 1.0f; yM[5] = 0.0f; yM[6] = -sinY; yM[7] = 0.0f; yM[8] = cosY; // rotation about z-axis (azimuth) zM[0] = cosZ; zM[1] = sinZ; zM[2] = 0.0f; zM[3] = -sinZ; zM[4] = cosZ; zM[5] = 0.0f; zM[6] = 0.0f; zM[7] = 0.0f; zM[8] = 1.0f; // rotation order is y, x, z (roll, pitch, azimuth) float temp[9]; matrixMultiplication(xM, yM, temp); matrixMultiplication(zM, temp, result); }
/// Computes lighting for the entire scene void computeLighting() { for (auto &ridge : mountains) { for (int i=0; i < ridge.meshVertices.size(); i = i+3) { // Compute for our (single) light Vec3Df vertexpos = Vec3Df(ridge.meshVertices[i], ridge.meshVertices[i+1], ridge.meshVertices[i+2]); Vec3Df normal = Vec3Df(ridge.meshNormals[i], ridge.meshNormals[i+1], ridge.meshNormals[i+2]); Vec3Df lighting = computeLighting(vertexpos, normal, DIFFUSE_LIGHTING); // Pass computed values to Ridge ridge.meshColors[i] = lighting[0]; ridge.meshColors[i+1] = lighting[1]; ridge.meshColors[i+2] = lighting[2]; } } if (toggleBoss) { std::vector<Vertex> vertices = boss.getMesh().vertices; std::vector<Vec3Df> meshColors = std::vector<Vec3Df>(vertices.size()); auto rotMat = matrixMultiplication( rotateMatrixY(boss.angleHeadY*M_PI / 180), rotateMatrixX(boss.angleHeadZ*M_PI / 180) ); for (int i = 0; i < vertices.size(); i++) { // Compute for our (single) light Vertex vertex = vertices[i]; Vec3Df vec = vertex.p; vec = calculateMatrix(rotMat, vec); vec = vec + boss.translation; vec = vec * boss.scale; vec = vec + boss.position; Vec3Df nor = vertex.n; nor = calculateMatrix(rotMat, nor); nor = nor + boss.translation; nor = nor * boss.scale; nor = nor + boss.position; Vec3Df lighting = computeLighting(vec, nor, PHONG_LIGHTNING); meshColors[i] = lighting; } boss.getMesh().meshColor = meshColors; } }
// This function performs the integration of the gyroscope data. // It writes the gyroscope based orientation into gyroOrientation. void gyroFunction(void) { //static double NS2S = 1.0f / 1000000000.0f; //double timestamp; // don't start until first accelerometer/magnetometer orientation has been acquired //if (accMagOrientation == null) //return; // initialisation of the gyroscope based rotation matrix static bool initState = true; if (initState) { double initMatrix[9]; getRotationMatrixFromOrientation(initMatrix, accMagOrientation); double test[3]; getOrientation(test, initMatrix); matrixMultiplication(gyroMatrix, gyroMatrix, initMatrix); initState = false; } // copy the new gyro values into the gyro array // convert the raw gyro data into a rotation vector double deltaVector[4]; //const double dT = (timer_systime() - timestamp) * NS2S; //System.arraycopy(event.values, 0, gyro, 0, 3); getRotationVectorFromGyro(deltaVector, G_Dt); // measurement done, save current time for next interval //timestamp = timer_systime(); // convert rotation vector into rotation matrix double deltaMatrix[9]; getRotationMatrixFromVector(deltaMatrix, deltaVector); // apply the new rotation interval on the gyroscope based rotation matrix matrixMultiplication(gyroMatrix, gyroMatrix, deltaMatrix); // get the gyroscope based orientation from the rotation matrix getOrientation(gyroMatrix, gyroOrientation); }
void compute() { int i, j; float angle; float **pt, **tmp; /* pt is 1 by 3 */ pt = (float**)mxCalloc(1,sizeof(*pt)); for( i = 0; i < 1; ++i ) { pt[i] = (float*)mxCalloc(3,sizeof(**pt)); } /* tmp is 1 by 3 */ tmp = (float**)mxCalloc(1,sizeof(*tmp)); for( i = 0; i < 1; ++i ) { tmp[i] = (float*)mxCalloc(3,sizeof(**tmp)); } /* set the transformation matrix */ A1 = (float**)mxCalloc(3,sizeof(*A1)); for( i = 0; i < 3; ++i ) { A1[i] = (float*)mxCalloc(3,sizeof(**A1)); } A2 = (float**)mxCalloc(3,sizeof(*A2)); for( i = 0; i < 3; ++i ) { A2[i] = (float*)mxCalloc(3,sizeof(**A2)); } for( i = 0; i < 3; ++i ) for( j = 0; j < 3; ++j ) { A1[i][j] = 0; A2[i][j] = 0; } A1[0][0] = cScale * pow( (double)2, (double)(tScale/2) ); A1[1][1] = rScale * pow( (double)2, (double)(tScale/2) ); angle = rotation * PI/nOri; A2[0][0] = cos(angle); A2[0][1] = sin(angle); A2[1][0] = -A2[0][1]; A2[1][1] = A2[0][0]; for( i = 0; i < nElement; ++i ) { tmp[0][0] = inCol[i]; tmp[0][1] = -inRow[i]; tmp[0][2] = 1; matrixMultiplication(1,3,tmp,3,A1,pt); tmp[0][0] = pt[0][0]; tmp[0][1] = pt[0][1]; tmp[0][2] = pt[0][2]; matrixMultiplication(1,3,tmp,3,A2,pt); outCol[i] = ROUND( pt[0][0] ); outRow[i] = ROUND( -pt[0][1] ); outO[i] = inO[i] + rotation; outS[i] = inS[i] + tScale; /* while( outO[i] < 0 ) outO[i] = outO[i] + nOri; while( outO[i] >= nOri ) outO[i] = outO[i] - nOri; */ } }
/*! * This sub-routine computes the velocity vector, given a magnitude, a unit normal vector from the * point on the surface where the regolith is lofted from, and the two conic angles which describe * the velocity vector's direction relative to the normal vector. A backwards approach is used * to go from the velocity vector in the final rotated intermediate frame back to the body fixed * frame. More details are given in the thesis report and author's personal notes. * */ void computeRegolithVelocityVector( std::vector< double > regolithPositionVector, const double velocityMagnitude, const double coneAngleAzimuth, const double coneAngleDeclination, std::vector< double > &unitNormalVector, std::vector< double > ®olithVelocityVector ) { // form the velocity vector, assuming that the intermediate frame's z-axis, on the surface of // the asteroid, is along the final velocity vector regolithVelocityVector[ 0 ] = 0.0; regolithVelocityVector[ 1 ] = 0.0; regolithVelocityVector[ 2 ] = velocityMagnitude; // get the rotatin matrix to go from the rotated intermediate frame back to the initial // frame where the z-axis was along the normal axis and the x-axis was pointing towards north // direction std::vector< std::vector< double > > zBasicRotationMatrix { { std::cos( coneAngleAzimuth ), std::sin( coneAngleAzimuth ), 0.0 }, { -std::sin( coneAngleAzimuth ), std::cos( coneAngleAzimuth ), 0.0 }, { 0.0, 0.0, 1.0 } }; std::vector< std::vector< double > > yBasicRotationMatrix { { std::cos( coneAngleDeclination ), 0.0, -std::sin( coneAngleDeclination ) }, { 0.0, 1.0, 0.0 }, { std::sin( coneAngleDeclination ), 0.0, std::cos( coneAngleDeclination ) } }; std::vector< std::vector< double > > nonTransposedRotationMatrix( 3, std::vector< double > ( 3 ) ); matrixMultiplication( yBasicRotationMatrix, zBasicRotationMatrix, nonTransposedRotationMatrix, 3, 3, 3, 3 ); std::vector< std::vector< double > > intermediateFrameRotationMatrix( 3, std::vector< double > ( 3 ) ); matrixTranspose( nonTransposedRotationMatrix, intermediateFrameRotationMatrix ); std::vector< std::vector< double > > rotatedIntermediateFrameVelocityVector { { regolithVelocityVector[ 0 ] }, { regolithVelocityVector[ 1 ] }, { regolithVelocityVector[ 2 ] } }; std::vector< std::vector< double > > intermediateFrameVelocityVector( 3, std::vector< double > ( 1 ) ); matrixMultiplication( intermediateFrameRotationMatrix, rotatedIntermediateFrameVelocityVector, intermediateFrameVelocityVector, 3, 3, 3, 1 ); // now obtain the basis vectors for the intermediate frame expressed in the // body fixed frame coordinates std::vector< double > xUnitVector( 3 ); std::vector< double > yUnitVector( 3 ); std::vector< double > zUnitVector( 3 ); zUnitVector = unitNormalVector; std::vector< double > bodyFrameZUnitVector { 0.0, 0.0, 1.0 }; // get the intermediate RTN frame at the surface point std::vector< double > unitR = normalize( regolithPositionVector ); std::vector< double > unitT = normalize( crossProduct( unitR, bodyFrameZUnitVector ) ); // get the x basis vector, pointing to north xUnitVector = normalize( crossProduct( unitT, zUnitVector ) ); // get the y basis vector yUnitVector = normalize( crossProduct( zUnitVector, xUnitVector ) ); std::vector< double > zPrincipalAxisBodyFrame { 0.0, 0.0, 1.0 }; std::vector< double > zNegativePrincipalAxisBodyFrame { 0.0, 0.0, -1.0 }; // check if the position vector is along the poles const double positionDotPrincipalZ = dotProduct( normalize( regolithPositionVector ), zPrincipalAxisBodyFrame ); const double positionDotNegativePrincipalZ = dotProduct( normalize( regolithPositionVector ), zNegativePrincipalAxisBodyFrame ); if( positionDotPrincipalZ == 1.0 ) { // the position vector is pointing to the poles, hence x basis vector pointing to the north // direction wouldn't work xUnitVector = { 1.0, 0.0, 0.0 }; yUnitVector = { 0.0, 1.0, 0.0 }; } else if( positionDotNegativePrincipalZ == 1.0 ) { xUnitVector = { -1.0, 0.0, 0.0 }; yUnitVector = { 0.0, 1.0, 0.0 }; } // put the basis vectors in a 3x3 matrix std::vector< std::vector< double > > intermediateFrameBasisMatrix { { xUnitVector[ 0 ], yUnitVector[ 0 ], zUnitVector[ 0 ] }, { xUnitVector[ 1 ], yUnitVector[ 1 ], zUnitVector[ 1 ] }, { xUnitVector[ 2 ], yUnitVector[ 2 ], zUnitVector[ 2 ] } }; std::vector< std::vector< double > > bodyFrameVelocityVector( 3, std::vector< double >( 1 ) ); matrixMultiplication( intermediateFrameBasisMatrix, intermediateFrameVelocityVector, bodyFrameVelocityVector, 3, 3, 3, 1 ); // return the final regolith velocity vector, expressed in body frame coordinates regolithVelocityVector[ 0 ] = bodyFrameVelocityVector[ 0 ][ 0 ]; regolithVelocityVector[ 1 ] = bodyFrameVelocityVector[ 1 ][ 0 ]; regolithVelocityVector[ 2 ] = bodyFrameVelocityVector[ 2 ][ 0 ]; }
int main(int argc, char **argv){ //LOCAL VARIABLE DEF BLOCK=========================================== image_ptr imagePtr; float subimg[sis][sis]; //space for subimage int rows, cols, type; int i, j, k, u, v, count; //counter variables int offset; //to keep track of values put into subImagePtr float scale; //to calcule img size int rowsize; int rowblock, colblock, totalblock; //number of sub blocks needed for image //float Z[1000000]; //this will be the compressed image unsigned char writeme[1000000]; //this is the unsigned char to write to file unsigned char childOut[100000]; //this is the unsigned char used for child output //int zc = 0; //counter for Z int wc = 0; //counter for writeme int dir; //direction of zig zag 0 = down 1 = up int zeros = 0; //holds the number of zeros for "percent zeros" calculation int total = 0; //total number of bits used in "percent zeros" calculation int tmp; //used in float to unsigned char conversion int numOfChildren = 0; int childBlock = 0; //arrays for math float C[sis][sis] = { {0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536}, {0.4904, 0.4157, 0.2778, 0.0975, -0.0975, -0.2778, -0.4157, -0.4904}, {0.4619, 0.1913, -0.1913, -0.4619, -0.4619, -0.1913, 0.1913, 0.4619}, {0.4157, -0.0975, -0.4904, -0.2778, 0.2778, 0.4904, 0.0975, -0.4157}, {0.3536, -0.3536, -0.3536, 0.3536, 0.3536, -0.3536, -0.3536, 0.3536}, {0.2778, -0.4904, 0.0975, 0.4157, -0.4157, -0.0975, 0.4904, -0.2778}, {0.1913, -0.4619, 0.4619, -0.1913, -0.1913, 0.4619, -0.4619, 0.1913}, {0.0975, -0.2778, 0.4157, -0.4904, 0.4904, -0.4157, 0.2778, -0.0975}}; float CT[sis][sis] = { {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975}, {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778}, {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157}, {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904}, {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904}, {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157}, {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778}, {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975}}; //same for array Q float Q[sis][sis] = { {8, 16, 24, 32, 40, 48, 56, 64}, {16, 24, 32, 40, 48, 56, 64, 72}, {24, 32, 40, 48, 56, 64, 72, 80}, {32, 40, 48, 56, 64, 72, 80, 88}, {40, 48, 56, 64, 72, 80, 88, 96}, {48, 56, 64, 72, 80, 88, 96, 104}, {56, 64, 72, 80, 88, 95, 104, 112}, {64, 72, 80, 88, 96, 104, 112, 120}}; float q[sis][sis]; for (i = 0; i < 8; i++){ for (j = 0; j < 8; j++){ q[i][j] = Q[i][j]; } } //GET COMMAND LINE INPUTS=========================================== if (argc != 5){ printf("wrong inputs: use %s imageIn.ppm imageOut.enc q p\n", argv[0]); return 0; } //READ INPUT IMAGE================================================== printf("Reading input image. . . \n"); imagePtr = read_pnm(argv[1], &rows, &cols, &type); printf("Image read successfully\n"); printf("rows=%d, cols=%d, type=%d \n", rows, cols, type); int tb; //total blocks to be processed int cb = 0; //current block int g; //counter tb = (rows / sis) * (cols / sis); //Place image into 2D array unsigned char myImg[rows][cols]; for (i = 0; i < rows; i++){ for (j = 0; j < cols; j++){ myImg[i][j] = imagePtr[i*cols+j]; } } //set q array to propperly scaled value, based on input int qin; qin = atoi(argv[3]); intTimesMatrix(q, qin); // clip q to be between 0 and 255 for (u = 0; u < sis; u++){ for (v = 0; v < sis; v++){ if (q[u][v] > 254) q[u][v] = 254; } } //get p int p; p = atoi(argv[4]); //create tmp variables for preforming math operations float CX[sis][sis]; float Y[sis][sis]; int r, c; //get row and col characters - assumes that image is smaller than 1000x1000 int row1, row2, row3; int col1, col2, col3; row1 = rows / 100; row2 = (rows - (row1 * 100)) / 10; row3 = (rows - (row1 * 100)) - (row2 * 10); col1 = cols / 100; col2 = (cols - col1 * 100) / 10; col3 = (cols - col1 * 100) - col2 * 10; //build header writeme[wc++] = row1 + '0'; writeme[wc++] = row2 + '0'; writeme[wc++] = row3 + '0'; writeme[wc++] = '$'; //end of block character writeme[wc++] = col1 + '0'; writeme[wc++] = col2 + '0'; writeme[wc++] = col3 + '0'; writeme[wc++] = '$'; writeme[wc++] = '8'; writeme[wc++] = '$'; writeme[wc++] = '8'; writeme[wc++] = '$'; writeme[wc++] = qin + '0'; writeme[wc++] = '$'; writeme[wc++] = '0'; writeme[wc++] = '0'; writeme[wc++] = '$'; //create placeholder to put estimated size in later for (i = 0; i < 7; i++){ writeme[wc++] = '0'; } writeme[wc++] = '$'; //STEP THROUGH INPUT IMAGE=========================================== int makepipes; float tm; int mt; int pipefds[2*p]; int pid; for (i = 0; i < rows; i = i + 8){ for (j = 0; j < cols; j = j + 8){ for (u = 0; u < sis; u++){ for (v = 0; v < sis; v++){ //cast to float to make math operations possible and level off for proper DCT values mt = (int) myImg[i+u][j+v]; tm = (float) mt; subimg[u][v] = tm - 128; //make sure Y and CX are clear Y[u][v] = 0; CX[u][v] = 0; } } cb++; //increment current block if (numOfChildren == 0){ //build all necessary pipes if (tb - cb < p){ //only make amount of pipes necessary makepipes = tb - cb + 1; } else { makepipes = p; } for (g = 0; g < makepipes; g++){ if (pipe(pipefds + g*2) < 0){ perror("Pipe"); exit(1); } } } numOfChildren++; if ((pid = fork()) == 0){ //zero means child //Perform first step of matrix multiplication CX = C*subimg matrixMultiplication(C, subimg, CX); //Perform second step of matrix multiplication Y = CX*CT matrixMultiplication(CX, CT, Y); //quantize Y by dividing element by element with q eleByEleMatrixDiv(Y, q); //undo the (-128) for (u = 0; u < sis; u++){ for (v = 0; v < sis; v++){ Y[u][v] = Y[u][v] + 128; } } //preform zig zag on Y, sore flat result in Z r = 0; //current row c = 0; //current col count = 0; dir = 0; //loop to preform zig zagging while (count < 64){ if (Y[r][c] < 128.4 && Y[r][c] > 127.5){ //count zeros zeros = (64 - count); //should probably just send this back to the parent //REMEMBER TO ADD ZEROS BACK TOGETHER WHEN READING BACK IN total = 64; //AND ADD TOTAL break; } if (r == 0 && c < 7){ tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; c++; if (Y[r][c] < 128.4 && Y[r][c] > 127.5){ zeros = (64 - count); total = 64; break; } tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; c--; r++; dir = 0; } else if (c == 0 && r < 7){ tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; r++; if (Y[r][c] < 128.4 && Y[r][c] > 127.5){ zeros = (64 - count); total = 64; break; } tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; r--; c++; dir = 1; } else if ( r == 7){ tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; c++; if (Y[r][c] < 128.4 && Y[r][c] > 127.5){ //count zeros zeros = (64 - count); total = 64; break; } tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; c++; r--; dir = 1; } else if ( c == 7){ tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; r++; if (Y[r][c] < 128.4 && Y[r][c] > 127.5){ //count zeros zeros = (64 - count); total = 64; break; } tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; r++; c--; dir = 0; } else if (dir == 0){ tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; c--; r++; } else if (dir == 1){ tmp = (int) Y[r][c]; childOut[count++] = (unsigned char) tmp; c++; r--; } } childOut[count++] = '$'; //need to add in percent zeros and block position //actually might not need to worry about positioning (use pipes to keep track) unsigned char results[count]; for (g = 0; g < count; g++){ results[g] = childOut[g]; } //return data //could add several '$' to mark end of transmitted data write(pipefds[(numOfChildren-1)*2+1], results, sizeof(results)); //kill child exit(0); } else if (pid == -1) { //fork error printf("Fork error\n"); exit(1); } else { //this is the parent if (numOfChildren >= makepipes){ //this means all children are made, need to get results //not sure how to make sure they are all finished or not? //wonder if it waits for something to be written? unsigned char tmpin[100]; //get data for (g = 0; g < makepipes; g++){ read(pipefds[2*g], tmpin, sizeof(tmpin)); int h = 0; while (tmpin[h] != '$'){ writeme[wc++] = tmpin[h++]; if (h > 99){ printf("something probably went wrong"); break; } } writeme[wc++] = '$'; //h is going to be equivilent to (64 - zeros) zeros = zeros + (64 - h); total = total + 64; } //close pipes for (g = 0; g < 2 * makepipes; g++){ close(pipefds[g]); } // all children should be dead at this point numOfChildren = 0; } } } } //change percent zeros in write me float pz; printf("This is total: %d\n", total); printf("This is zeros: %d\n", zeros); pz = (float) zeros / total; printf("Percent Zeros: %f\n", pz); pz = (int) (pz * 100); int pz1; pz1 = pz / 10; int pz2; pz2 = pz - pz1 * 10; writeme[14] = pz1 + '0'; writeme[15] = pz2 + '0'; //change estimated size //estimated size is zc, so get each element then plug into Z[17 - 24] int zc1, zc2, zc3, zc4, zc5, zc6, zc7; zc1 = wc / 1000000; zc2 = (wc - zc1 * 1000000) / 100000; zc3 = (wc - zc1 * 1000000 - zc2 * 100000) / 10000; zc4 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000) / 1000; zc5 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000 - zc4 * 1000) / 100; zc6 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000 - zc4 * 1000 - zc5 * 100) / 10; zc7 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000 - zc4 * 1000 - zc5 * 100 - zc6 * 10); writeme[17] = zc1 + '0'; writeme[18] = zc2 + '0'; writeme[19] = zc3 + '0'; writeme[20] = zc4 + '0'; writeme[21] = zc5 + '0'; writeme[22] = zc6 + '0'; writeme[23] = zc7 + '0'; //write file FILE *f = fopen(argv[2], "w"); if (f == NULL){ printf("Error opening file\n"); return 0; } for (i = 0; i < wc; i++){ fprintf(f, "%c", writeme[i]); } fclose(f); }