World Space 与 canonical view volume 是两个不同的空间 World Space (起点) $\xrightarrow{\text{相机变换}}$ Camera Space $\xrightarrow{\text{投影变换}}$ Canonical View Volume (中转站) $\xrightarrow{\text{视口变换}}$ Screen Space
The Viewport Transformation
规范视体积” (canonical view volume) 中,并且我们希望用一个看向 $-z$ 方向的正交相机来观察它,规范视体积是一个包含所有笛卡尔坐标在 $-1$ 和 $+1$ 之间的 3D 点的立方体——即 $(x, y, z) \in [-1, 1]^3$ 典型视图体积是一个边长为二、以原点为中心的立方体。
construct M_vp // 构建视口变换矩阵 construct M_orth // 构建正交投影矩阵 M = M_vp * M_orth // 关键步骤:矩阵预合并! for each line segment (a_i, b_i) do // 遍历每一条线 p = M * a_i // 用合并后的矩阵变换点 a q = M * b_i // 用合并后的矩阵变换点 b drawline(x_p, y_p, x_q, y_q) // 画线(只用 x, y 坐标)
相机变换 (The Camera Transformation)
我们希望能能够在 3D 空间中改变视点,并朝向任意方向观察。关于如何指定观察者的位置和朝向,存在许多不同的惯例。我们将采用如下定义 :
construct M_vp // 构建视口矩阵 construct M_orth // 构建正交投影矩阵 construct M_cam // 构建相机变换矩阵 M = M_vp M_orth M_cam // 将它们乘在一起(注意顺序:先乘相机,再投影,最后视口) for each line segment (a_i, b_i) do // 遍历每条线段 p = M a_i // 变换点 a q = M b_i // 变换点 b drawline(x_p, y_p, x_q, y_q) // 画线
int main() { double fahrenheit; printf("This program converts fahrenheit to celsius and kelvin.\n"); printf("Enter a temperature in dgrees fahrenheit (q to quit):"); while(scanf("%lf", &fahrenheit) == 1) // continue executing loop if user enters valid number { Temperatures(fahrenheit); // convert fahrenheit to celsius and kelvin
//prompt for new input printf("Enter a temperatures in degrees fahrenheit (q to quit):"); } printf("Bye!\n"); }
do // get uppercase letter from user { printf("Enter an uppercases letter:"); scanf("%c", &uppercase_letter); }while (uppercase_letter < 'A'|| 'Z' < uppercase_letter);
int main() { char line[255]; int i = 0; // array printf("Enter a line to reerse:\n"); while (scanf("%c", &line[i]), line[i] != '\n') i++; for (; 0 <= i; i--) //previous loop leaves i in right postion printf("%c", line[i]); return 0; }
line[i] != ‘\n’ 的条件判断使得循环在用户输入的行中包含换行符之前继续执行。当用户按下 Enter 键时,输入的换行符会被检测到,并导致循环结束。
int main(void) { char ch; unsigned int ei_count = 0; bool e_flag = false;
printf("This program reads input and counts the number of times the\n" "sequence 'ei' occurs (case insensitive).\n"); printf("Enter input (%c to stop):\n", STOP);
while ((ch = getchar()) != STOP) { ch = tolower(ch); if (ch == 'e') e_flag = true; else if (ch == 'i') { if (e_flag) ei_count++; e_flag = false; } else e_flag = false;
***************************************************************** Enter the number corresponding to the desired pay rate or action: 1) $8.75/hr 2) $9.33/hr 2) $10.00/hr 4) $11.20/hr 3) quit *****************************************************************
int main() { bool exit_flag = false; int rate_option; double rate, hours, gross_pay, taxes,net_pay;
while (1) { printf("*****************************************************************\n"); printf("Enter the number corresponding to the desired pay rate or action:\n"); printf("1) $8.75/hr 2) $9.33/hr\n"); printf("3) $10.00/hr 4) $11.20/hr\n"); printf("5) quit\n"); printf("*****************************************************************\n");
scanf("%d", &rate_option); switch (rate_option) { case 1: rate = RATE_1; break; case 2: rate = RATE_2; break; case 3: rate = RATE_3; break; case 4: rate = RATE_4; break; case 5: exit_flag = true; break; default: //invalid input flush_input_buffer(); printf("please enter an integer between 1 and 5.\n"); continue; // repeat main program loop }
if (exit_flag) break; //exit program
printf("Enter the number of hours worked in a week:"); while (scanf("%lf", &hours) != 1 || hours <= 0) { flush_input_buffer(); printf("please enter a positive number.\n"); printf("Enter number of hours worked in a week:"); }
while (1){ printf("What would you like to order?\n"); printf("a) artichoke b) beet c) carrot q) quit\n"); option = getchar(); switch(option) { case ('q'): printf("Bye.\n"); return 0; //exit program
case ('a'): //artichokes printf("How many pound of artichokes would you like to add?"); if (scanf("%f", &weight) == 1) artichokeWeight += weight; else { flush_input_buffer(); printf("Invalid input. Try again.\n"); continue; //repeat main program loop } break;
case ('b'): //beets printf("How many pounds of beets would you like to add?"); if (scanf("%f", &weight) == 1) beetWeight += weight; else { flush_input_buffer(); printf("Invalid input. Try again.\n"); continue; //repeat main program loop } break;
case ('c')://carrots printf("How many pounds of carrots would you like to add?"); if (scanf("%f", &weight) == 1) carrotWeight += weight; else { flush_input_buffer(); printf("Invalid input. Try again.\n"); continue; //repeat main program loop } break; default: printf("Invalid input. Try again.\n"); continue; //repeat main program loop } //calculate subtotal artichokePrice = artichokeWeight * ARTICHOKE_PRICE_PER_LB; beetPrice = beetWeight * BEET_PRICE_PER_LB; carrotWeight = carrotWeight * CARROT_PRICE_PER_LB; subtotal = artichokePrice + beetPrice + carrotPrice;
void copy_2dim_arr(int rows, int cols, double source[rows][cols], double target[rows][cols]) { // copy one two-dimensional array to another for (int i = 0; i < rows; i++){ for (int j = 0; j < cols; j++) target[i][j] = source[i][j]; } }
void print_2dim_arr(int rows, int cols, double arr[rows][cols]) { //print the contents of a two-dimensional array
for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) printf(" %10.3f ", arr[i][j]);
#define SIZE 10 void add_arrays(int *addend1, int *addend2, int *sum, int array_length);
int main() { //test add_arrays srand(time(NULL));
int array1[SIZE]; int array2[SIZE]; int sum[SIZE];
// initialize arrays with random ints for (int i = 0; i < SIZE; i++) { array1[i] = rand() % 20; array2[i] = rand() % 20; }
// get sum of arrays add_arrays(array1, array2, sum, SIZE);
//print arrays printf("%8s %8s %8s\n", "Array 1", "Array 2", "Sum"); for (int i = 0; i < SIZE; i++) printf("%8d %8d %8d\n", array1[i], array2[i], sum[i]);
return 0; }
void add_arrays(int *addend1, int *addend2, int *sum, int array_length) { // calculate elementwise sum of two arrays for (int *tar = sum; tar < sum + array_length; tar++, addend1++, addend2++) *tar = *addend1 + *addend2; }
void input_data(int rows, int columns, double array[][5]); double compute_row_average(double *array, int cols); double compute_array_average(int rows, int cols, double array[rows][cols]); double largest_vlue(int rows, int cols, double array[rows][cols]);
int main() { double data[ROWS][COLUMNS];
input_data(ROWS, COLUMNS, data);
//print row averages printf("Row Averages:\n"); for (int i = 0; i < ROWS; i++) { printf("\t Average for row %d: %3.f\n", i + 1, compute_row_average(data[i], COLUMNS)); }
//print array average printf("Average for entire array: %.3f\n", compute_array_average(ROWS,COLUMNS, data));
// print largest value printf("Maximum array value: %.3f\n", largest_vlue(ROWS, COLUMNS, data));
return 0; }
void input_data(int rows, int columns, double array[][5]) { printf("Enter 3 groups of 5 double values each:\n"); for (int i = 0; i < rows; i++) { printf("Grop %d:", i + 1); for (int j = 0; j < columns; j++) scanf("%lf", array[i] + j); } }
double compute_row_average(double *array, int cols) { double total = 0; for (int i = 0; i < cols; i++) total += array[i];
return total / cols; }
double compute_array_average(int rows, int cols, double array[rows][cols]) { double total = 0; for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) total += array[i][j];
return total / (rows * cols); }
double largest_vlue(int rows, int cols, double array[rows][cols]) { double max = array[0][0]; for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) if (array[i][j] > max) max = array[i][j];
void sort_ASCII(char *strings[], int n) { // sort array of string pointers by ASCII collating sequence
char *tmp;
for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if (strcmp(strings[i], strings[j]) > 0) { tmp = strings[i]; strings[i] = strings[j]; strings[j] = tmp; } } }
void sort_length(char *strings[], int n) { // sort array of string pointer by length
char *tmp;
// 冒泡排序 for (int i = 0; i < n - 1; i++) for (int j = i + 1; j < n; j++) { if (strlen(strings[i]) > strlen(strings[j])) { tmp = strings[i]; strings[i] = strings[j]; strings[j] = tmp; } } }
int fwlen(char *string) { // return length of first word of string
int length = 0;
// skip leading whitespace while (isspace(*string)) string++;
// count first word length while (!isspace(*string)) { length++; string++; } return length; }
void sort_firstword_length(char *strings[], int n) { // sort array of string pointers by ASCII collating sequence
char *tmp;
for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) { if (fwlen(strings[i]) > fwlen(strings[j])) { tmp = strings[i]; strings[i] = strings[j]; strings[j] = tmp; } } }
char * get(char *string, int n) { // wrapper for fgets that repalces first newline with null
char *ret_val = fgets(string, n, stdin); while (*string != '\0') { if (*string == '\n') *string = '\0'; string++; } return ret_val; }
void print_menu(void) { puts("Choose an option: "); puts("(o) Print strings in original order."); puts("(a) Print strings in ASCII collating sequence."); puts("(l) Print strings ordered by length."); puts("(f) Print strings ordered by length of the first word."); puts("(q) Quit."); puts(""); puts("Enter a character: "); }
int sum(const int ar[], int n); /* 函数原型 */ int sum(const int ar[], int n) /* 函数定义 */ { int i; int total = 0; for( i = 0; i < n; i++) total += ar[i]; return total; }
下面是一个类函数宏: #define PSQR(X) printf("The square of X is %d.\n", ((X)*(X))); 假设这样使用宏: PSQR(8); 输出为: The square of X is 64. C允许在字符串中包含宏参数。在类函数宏的替换体中,#号作为一个预处理运算符,可以把记号转换成字符串。例如,如果x是一个宏形参,那么#x就是转换为字符串”x”的形参名。这个过程称为字符串化(stringizing)。
1 2 3 4 5 6 7 8 9 10 11 12 13
/* subst.c -- 在字符串中替换 */ #include <stdio.h> #define PSQR(x) printf("The square of " #x " is %d.\n",((x)*(x))) int main(void) { int y = 5; PSQR(y); PSQR(2 + 4); return 0; } 该程序的输出如下: The square of y is 25. The square of 2 + 4 is 36.
ag -g <File Name> # 类似于 find . -name <File Name> ag -i PATTERN # 忽略大小写搜索含PATTERN文本 ag -A [number] PATTERN #搜索含PATTERN文本,并显示匹配内容之后的n行文本,例如:ag -A 5 abc会显示搜索到的包含abc的行以及它之后5行的文本信息。 ag -B [number] PATTERN #搜索含PATTERN文本,并显示匹配内容之前的n行文本 ag -C [number] PATTERN #搜索含PATTERN文本,并同时显示匹配内容以及它前后各n行文本的内容。 ag --ignore-dir <Dir Name> #忽略某些文件目录进行搜索。 ag -w PATTERN #全匹配搜索,只搜索与所搜内容完全匹配的文本。 ag --java PATTERN #在java文件中搜索含PATTERN的文本。 ag --xml PATTERN #在XML文件中搜索含PATTERN的
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.