diff --git a/ass b/ass index 26c7eba..9038a36 100755 Binary files a/ass and b/ass differ diff --git a/elementdata.c b/elementdata.c index 59bc659..4e17684 100644 --- a/elementdata.c +++ b/elementdata.c @@ -1,4 +1,5 @@ -// Periodic Table CVS file from https://github.com/Bowserinator/Periodic-Table-JSON +// Periodic Table CVS file from +// https://github.com/Bowserinator/Periodic-Table-JSON #include #include @@ -9,178 +10,187 @@ #define MAX_CSV_LINE_LENGTH 2048 typedef struct { - char name[50]; - char appearance[100]; - double atomic_mass; - double boil; - char category[50]; - double density; - char discovered_by[50]; - double melt; - double molar_heat; - char named_by[50]; - int number; - int period; - int group; - char phase[10]; - char source[100]; - char bohr_model_image[200]; - char bohr_model_3d[200]; - char spectral_img[200]; - char summary[500]; - char symbol[3]; - int xpos; - int ypos; - int wxpos; - int wypos; - char shells[50]; - char electron_configuration[50]; - char electron_configuration_semantic[50]; - double electron_affinity; - double electronegativity_pauling; - char ionization_energies[200]; - char cpk_hex[10]; - char block[2]; - char image_title[200]; - char image_url[200]; - char image_attribution[200]; + char name[50]; + char appearance[100]; + double atomic_mass; + double boil; + char category[50]; + double density; + char discovered_by[50]; + double melt; + double molar_heat; + char named_by[50]; + int number; + int period; + int group; + char phase[10]; + char source[100]; + char bohr_model_image[200]; + char bohr_model_3d[200]; + char spectral_img[200]; + char summary[500]; + char symbol[3]; + int xpos; + int ypos; + int wxpos; + int wypos; + char shells[50]; + char electron_configuration[50]; + char electron_configuration_semantic[50]; + double electron_affinity; + double electronegativity_pauling; + char ionization_energies[200]; + char cpk_hex[10]; + char block[2]; + char image_title[200]; + char image_url[200]; + char image_attribution[200]; } Element; // Function to trim leading and trailing whitespaces -char* trimWhitespace(char* str) { - char* end; +char *trimWhitespace(char *str) { + char *end; - // Trim leading space - while(isspace((unsigned char)*str)) str++; - - if(*str == 0) // All spaces? - return str; - - // Trim trailing space - end = str + strlen(str) - 1; - while(end > str && isspace((unsigned char)*end)) end--; - - // Write new null terminator character - end[1] = '\0'; + // Trim leading space + while (isspace((unsigned char)*str)) + str++; + if (*str == 0) // All spaces? return str; + + // Trim trailing space + end = str + strlen(str) - 1; + while (end > str && isspace((unsigned char)*end)) + end--; + + // Write new null terminator character + end[1] = '\0'; + + return str; } // Function to parse a CSV line considering quoted fields -void parseCSVLine(char* line, char** fields, int field_count) { - int field_index = 0; - int in_quotes = 0; - char* field_start = line; +void parseCSVLine(char *line, char **fields, int field_count) { + int field_index = 0; + int in_quotes = 0; + char *field_start = line; - for (char* p = line; *p; p++) { - if (*p == '\"') { - in_quotes = !in_quotes; // Toggle quote state - } else if (*p == ',' && !in_quotes) { - *p = '\0'; - fields[field_index++] = trimWhitespace(field_start); - field_start = p + 1; - } + for (char *p = line; *p; p++) { + if (*p == '\"') { + in_quotes = !in_quotes; // Toggle quote state + } else if (*p == ',' && !in_quotes) { + *p = '\0'; + fields[field_index++] = trimWhitespace(field_start); + field_start = p + 1; } + } - fields[field_index] = trimWhitespace(field_start); + fields[field_index] = trimWhitespace(field_start); } // Function to parse the CSV file -Element* parseCSV(const char* filename, int* element_count) { - FILE* file = fopen(filename, "r"); - if (!file) { - perror("Unable to open file"); - return NULL; - } - - Element* elements = (Element*)malloc(MAX_ELEMENTS * sizeof(Element)); - if (!elements) { - perror("Unable to allocate memory"); - fclose(file); - return NULL; - } - - char line[MAX_CSV_LINE_LENGTH]; - fgets(line, sizeof(line), file); // Skip the header line - - *element_count = 0; - while (fgets(line, sizeof(line), file)) { - if (*element_count >= MAX_ELEMENTS) break; - - char* fields[35] = {0}; // Array to hold all fields in the CSV line - parseCSVLine(line, fields, 35); - - Element elem = {0}; // Initialize all struct members to zero or empty - - strncpy(elem.name, fields[0], sizeof(elem.name) - 1); - strncpy(elem.appearance, fields[1], sizeof(elem.appearance) - 1); - elem.atomic_mass = atof(fields[2]); - elem.boil = atof(fields[3]); - strncpy(elem.category, fields[4], sizeof(elem.category) - 1); - elem.density = atof(fields[5]); - strncpy(elem.discovered_by, fields[6], sizeof(elem.discovered_by) - 1); - elem.melt = atof(fields[7]); - elem.molar_heat = atof(fields[8]); - strncpy(elem.named_by, fields[9], sizeof(elem.named_by) - 1); - elem.number = atoi(fields[10]); - elem.period = atoi(fields[11]); - elem.group = atoi(fields[12]); - strncpy(elem.phase, fields[13], sizeof(elem.phase) - 1); - strncpy(elem.source, fields[14], sizeof(elem.source) - 1); - strncpy(elem.bohr_model_image, fields[15], sizeof(elem.bohr_model_image) - 1); - strncpy(elem.bohr_model_3d, fields[16], sizeof(elem.bohr_model_3d) - 1); - strncpy(elem.spectral_img, fields[17], sizeof(elem.spectral_img) - 1); - strncpy(elem.summary, fields[18], sizeof(elem.summary) - 1); - strncpy(elem.symbol, fields[19], sizeof(elem.symbol) - 1); - elem.xpos = atoi(fields[20]); - elem.ypos = atoi(fields[21]); - elem.wxpos = atoi(fields[22]); - elem.wypos = atoi(fields[23]); - strncpy(elem.shells, fields[24], sizeof(elem.shells) - 1); - strncpy(elem.electron_configuration, fields[25], sizeof(elem.electron_configuration) - 1); - strncpy(elem.electron_configuration_semantic, fields[26], sizeof(elem.electron_configuration_semantic) - 1); - elem.electron_affinity = atof(fields[27]); - elem.electronegativity_pauling = atof(fields[28]); - strncpy(elem.ionization_energies, fields[29], sizeof(elem.ionization_energies) - 1); - strncpy(elem.cpk_hex, fields[30], sizeof(elem.cpk_hex) - 1); - strncpy(elem.block, fields[31], sizeof(elem.block) - 1); - strncpy(elem.image_title, fields[32], sizeof(elem.image_title) - 1); - strncpy(elem.image_url, fields[33], sizeof(elem.image_url) - 1); - strncpy(elem.image_attribution, fields[34], sizeof(elem.image_attribution) - 1); - - elements[*element_count] = elem; - (*element_count)++; - } +Element *parseCSV(const char *filename, int *element_count) { + FILE *file = fopen(filename, "r"); + if (!file) { + perror("Unable to open file"); + return NULL; + } + Element *elements = (Element *)malloc(MAX_ELEMENTS * sizeof(Element)); + if (!elements) { + perror("Unable to allocate memory"); fclose(file); - return elements; -} + return NULL; + } + char line[MAX_CSV_LINE_LENGTH]; + fgets(line, sizeof(line), file); // Skip the header line + + *element_count = 0; + while (fgets(line, sizeof(line), file)) { + if (*element_count >= MAX_ELEMENTS) + break; + + char *fields[35] = {0}; // Array to hold all fields in the CSV line + parseCSVLine(line, fields, 35); + + Element elem = {0}; // Initialize all struct members to zero or empty + + strncpy(elem.name, fields[0], sizeof(elem.name) - 1); + strncpy(elem.appearance, fields[1], sizeof(elem.appearance) - 1); + elem.atomic_mass = atof(fields[2]); + elem.boil = atof(fields[3]); + strncpy(elem.category, fields[4], sizeof(elem.category) - 1); + elem.density = atof(fields[5]); + strncpy(elem.discovered_by, fields[6], sizeof(elem.discovered_by) - 1); + elem.melt = atof(fields[7]); + elem.molar_heat = atof(fields[8]); + strncpy(elem.named_by, fields[9], sizeof(elem.named_by) - 1); + elem.number = atoi(fields[10]); + elem.period = atoi(fields[11]); + elem.group = atoi(fields[12]); + strncpy(elem.phase, fields[13], sizeof(elem.phase) - 1); + strncpy(elem.source, fields[14], sizeof(elem.source) - 1); + strncpy(elem.bohr_model_image, fields[15], + sizeof(elem.bohr_model_image) - 1); + strncpy(elem.bohr_model_3d, fields[16], sizeof(elem.bohr_model_3d) - 1); + strncpy(elem.spectral_img, fields[17], sizeof(elem.spectral_img) - 1); + strncpy(elem.summary, fields[18], sizeof(elem.summary) - 1); + strncpy(elem.symbol, fields[19], sizeof(elem.symbol) - 1); + elem.xpos = atoi(fields[20]); + elem.ypos = atoi(fields[21]); + elem.wxpos = atoi(fields[22]); + elem.wypos = atoi(fields[23]); + strncpy(elem.shells, fields[24], sizeof(elem.shells) - 1); + strncpy(elem.electron_configuration, fields[25], + sizeof(elem.electron_configuration) - 1); + strncpy(elem.electron_configuration_semantic, fields[26], + sizeof(elem.electron_configuration_semantic) - 1); + elem.electron_affinity = atof(fields[27]); + elem.electronegativity_pauling = atof(fields[28]); + strncpy(elem.ionization_energies, fields[29], + sizeof(elem.ionization_energies) - 1); + strncpy(elem.cpk_hex, fields[30], sizeof(elem.cpk_hex) - 1); + strncpy(elem.block, fields[31], sizeof(elem.block) - 1); + strncpy(elem.image_title, fields[32], sizeof(elem.image_title) - 1); + strncpy(elem.image_url, fields[33], sizeof(elem.image_url) - 1); + strncpy(elem.image_attribution, fields[34], + sizeof(elem.image_attribution) - 1); + + elements[*element_count] = elem; + (*element_count)++; + } + + fclose(file); + return elements; +} int testParser() { - int element_count; - Element* elements = parseCSV("resources/periodictable.csv", &element_count); - if (elements) { - for (int i = 0; i < element_count; i++) { - printf("Element: %s (%s)\n", elements[i].name, elements[i].symbol); - printf("Atomic Mass: %.2f\n", elements[i].atomic_mass); - printf("Category: %s\n", elements[i].category); - printf("Atomic Number: %d\n", elements[i].number); - printf("Period: %d\n", elements[i].period); - printf("Group: %d\n", elements[i].group); - printf("Phase: %s\n", elements[i].phase); - printf("Summary: %s\n", elements[i].summary); - printf("Shells: %s\n", elements[i].shells); - printf("Electron Configuration: %s\n", elements[i].electron_configuration); - printf("Electron Configuration Semantic: %s\n", elements[i].electron_configuration_semantic); - printf("Electron Affinity: %.2f\n", elements[i].electron_affinity); - printf("Electronegativity Pauling: %.2f\n", elements[i].electronegativity_pauling); - printf("Ionization Energies: %s\n", elements[i].ionization_energies); - printf("CPK Hex Color: %s\n", elements[i].cpk_hex); - printf("Block: %s\n", elements[i].block); - } - free(elements); + int element_count; + Element *elements = parseCSV("resources/periodictable.csv", &element_count); + if (elements) { + for (int i = 0; i < element_count; i++) { + printf("Element: %s (%s)\n", elements[i].name, elements[i].symbol); + printf("Atomic Mass: %.2f\n", elements[i].atomic_mass); + printf("Category: %s\n", elements[i].category); + printf("Atomic Number: %d\n", elements[i].number); + printf("Period: %d\n", elements[i].period); + printf("Group: %d\n", elements[i].group); + printf("Phase: %s\n", elements[i].phase); + printf("Summary: %s\n", elements[i].summary); + printf("Shells: %s\n", elements[i].shells); + printf("Electron Configuration: %s\n", + elements[i].electron_configuration); + printf("Electron Configuration Semantic: %s\n", + elements[i].electron_configuration_semantic); + printf("Electron Affinity: %.2f\n", elements[i].electron_affinity); + printf("Electronegativity Pauling: %.2f\n", + elements[i].electronegativity_pauling); + printf("Ionization Energies: %s\n", elements[i].ionization_energies); + printf("CPK Hex Color: %s\n", elements[i].cpk_hex); + printf("Block: %s\n", elements[i].block); } - return 0; + free(elements); + } + return 0; } - diff --git a/main.c b/main.c index 32feac1..edb41d4 100644 --- a/main.c +++ b/main.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { // normalizeCoordinates(&mol, screenWidth, screenHeight); int element_count; - Element* elements = parseCSV("resources/periodictable.csv", &element_count); + Element *elements = parseCSV("resources/periodictable.csv", &element_count); D printf("Number of atoms: %d\n", mol.num_atoms); for (int i = 0; i < mol.num_atoms; i++) { @@ -46,7 +46,8 @@ int main(int argc, char *argv[]) { camera.target = (Vector3){5.0f, 5.0f, 5.0f}; // Set camera target camera.up = (Vector3){0.0f, 1.0f, 0.0f}; // Set camera up vector camera.fovy = 45.0f; // Set camera field of view - // camera.projection = CAMERA_ORTHOGRAPHIC; // Camera projection type + // camera.projection = CAMERA_ORTHOGRAPHIC; // Camera projection + // type camera.projection = CAMERA_PERSPECTIVE; // Camera projection type int cameraMode = CAMERA_THIRD_PERSON; @@ -123,7 +124,6 @@ int main(int argc, char *argv[]) { free(elements); - CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- @@ -135,7 +135,8 @@ void drawAtom(Atom atom) { float radius; int scalingFactor = 100; -// radius is empirical from https://en.wikipedia.org/wiki/Atomic_radii_of_the_elements_(data_page) + // radius is empirical from + // https://en.wikipedia.org/wiki/Atomic_radii_of_the_elements_(data_page) if (strcmp(atom.atom_type, "C") == 0) { color = BLACK; radius = 70.0f / scalingFactor; @@ -160,20 +161,21 @@ void drawAtom(Atom atom) { } void drawBond(Atom atom) { - Color bondColor = GREEN; - for (int j = 0; j < atom.num_neighbours; j++) { - if (!atom.bonds_drawn) { - if (atom.bond_orders[j] > 1) { - bondColor = BLUE; - } - - DrawCylinderWiresEx( - (Vector3){atom.x, atom.y, atom.z}, - (Vector3){atom.neighbours[j]->x, - atom.neighbours[j]->y, - atom.neighbours[j]->z}, - 0.1f, 0.1f, 20, bondColor); - } - atom.bonds_drawn = true; + Color bondColor = GREEN; + for (int j = 0; j < atom.num_neighbours; j++) { + if (!atom.bonds_drawn) { + if (atom.bond_orders[j] == 2) { + bondColor = BLUE; + } else if (atom.bond_orders[j] >= 3) { + bondColor = RED; } + + DrawCylinderWiresEx((Vector3){atom.x, atom.y, atom.z}, + (Vector3){atom.neighbours[j]->x, + atom.neighbours[j]->y, + atom.neighbours[j]->z}, + 0.1f, 0.1f, 20, bondColor); + } + atom.bonds_drawn = true; + } }