版权声明:原创博文,若需转载,请与博主联系 https://blog.csdn.net/qq_38958113/article/details/82738244
- Utah.cpp
#include "stdafx.h"
#include "Utah.h"
#include <math.h>
#define M_PI 3.14159265358979323846
#define MAX_LOADSTRING 100
#define Xc 0
#define Yc 0
#define Zc 0 //视点
/*自定义变量*/
HDC hdcValue; // 窗口句柄
double Point[3][4][4]; //控制点数据缓存
double U[4]; //矩阵U
double W[4]; //矩阵W
void turnLarge(double x, double y, double z); //三维正向放大投影曲面
void turnLargeReverse(double x, double y, double z);//三维反向放大投影曲面
void turn(float x, float y); //旋转投影
void trixmulSurface(); //画曲面的自定义矩阵运算
void DrawCurve(float X[4], float Y[4], int n); //画壶体和壶盖
void matrixComputing(int iTemp); //循环计算x,y,z
void trixmulSurface(); //更换曲面数据绘制曲面
double matrixRealize(int dimension); //矩阵计算实现 S(u,w)=UMBM(t)W(t)
/*三维正向放大投影后绘制曲面*/
void turnLarge(double x, double y, double z) {
double _x;
double _y;
for (double i = 0; i < 360; i += 2) {
_x = -x * Zc + Xc * z;
_y = -y * Zc + Yc * z;
SetPixel(hdcValue, 500 + (-1)*int(_x * 20), 300 + int(_y * 20), RGB(102, 102, 102));
}
}
/*三维反向放大投影后绘制曲面*/
void turnLargeReverse(double x, double y, double z) {
double _x;
double _y;
for (double i = 0; i < 360; i += 8) {
_x = -x * Zc + Xc * z;
_y = -y * Zc + Yc * z;
SetPixel(hdcValue, 500 + int(_x * 20), 300 + int(_y * 20), RGB(102, 102, 102));
}
}
/*更换曲面数据绘制曲面*/
void trixmulSurface() {
int i = 0;
for (i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
Point[0][j][k] = _X[i][j][k];
Point[1][j][k] = _Y[i][j][k];
Point[2][j][k] = _Z[i][j][k];
}
}
matrixComputing(i);
}
}
/*循环计算x,y,z*/
void matrixComputing(int iTemp) {
double finalx = 0;
double finaly = 0;
double finalz = 0;
for (double u = 0; u < 1; u += 0.1) {
for (int i = 0; i < 4; i++) {
U[i] = pow(u, 3 - i);
}
for (double w = 0; w < 1; w += 0.01) {
for (int i = 0; i < 4; i++) {
W[i] = pow(w, 3 - i);
}
finalx = matrixRealize(0);
finaly = matrixRealize(1);
finalz = matrixRealize(2);
if (iTemp > 1) {
turnLarge(finalx, finaly, finalz);
}
else {
turnLargeReverse(finalx, finaly, finalz);
}
}
}
for (double u = 0; u < 1; u += 0.01) {
for (int i = 0; i < 4; i++) {
U[i] = pow(u, 3 - i);
}
for (double w = 0; w < 1; w += 0.1) {
for (int i = 0; i < 4; i++) {
W[i] = pow(w, 3 - i);
}
finalx = matrixRealize(0);
finaly = matrixRealize(1);
finalz = matrixRealize(2);
if (iTemp > 1) {
turnLarge(finalx, finaly, finalz);
}
else {
turnLargeReverse(finalx, finaly, finalz);
}
}
}
}
/*矩阵计算实现*/
double matrixRealize(int dimension) {
double TEM[4];
double TEM1[4];
double final = 0.0;
for (int i = 0; i < 4; i++) {
TEM[i] = M[i][0] * U[0] + M[i][1] * U[1] + M[i][2] * U[2] + M[i][3] * U[3];
}
for (int i = 0; i < 4; i++) {
TEM1[i] = Point[dimension][i][0] * TEM[0] + Point[dimension][i][1] * TEM[1] + Point[dimension][i][2] * TEM[2] + Point[dimension][i][3] * TEM[3];
}
for (int i = 0; i < 4; i++) {
TEM[i] = TEM1[i];
}
for (int i = 0; i < 4; i++) {
TEM1[i] = M[i][0] * TEM[0] + M[i][1] * TEM[1] + M[i][2] * TEM[2] + M[i][3] * TEM[3];
}
for (int i = 0; i < 4; i++) {
TEM[i] = TEM1[i];
}
for (int i = 0; i < 4; i++) {
final += W[i] * TEM[i];
}
for (int i = 0; i < 4; i++) {
TEM[i] = 0;
TEM1[i] = 0;
}
return final;
}
/*旋转投影*/
void turn(float x, float y) {
double _x;
double _y;
double xFinal;
double yFinal;
for (double i = 0; i < 360; i += 8) {
if ((int)(x*1000) == 0 || (int)(x * 1000) == 300 || (int)(x * 1000) == 450 || (int)(x * 1000) == 600 || (int)(x * 1000) == 750 || (int)(x * 1000) == 900 || (int)(x * 1000) == 1050 || (int)(x * 1000) == 1200|| (int)(x * 1000) == 1350 || (int)(x * 1000) == 1500|| (int)(x * 1000) == 1650 || (int)(x * 1000) == 1800|| (int)(x * 1000) == 1950 || (int)(x * 1000) == 2100|| (int)(x * 1000) == 2250 || (int)(x * 1000) == 2400|| (int)(x * 1000) == 2700|| (int)(x * 1000) == 3000) {
for (int j = 0; j < 360; j += 1) {
xFinal = -x * cos(j*M_PI / 180.0)*Zc + Xc * (-x * sin(j*M_PI / 180.0)); //先乘旋转矩阵,再投影
yFinal = -y * Zc + (-x * sin(j*M_PI / 180.0))*Yc;
SetPixel(hdcValue, 500 + int(xFinal * 20), 300 + int(yFinal * 20), RGB(102, 102, 102)); //平移放大
}
}
_x = -x * cos(i*M_PI / 180.0)*Zc + Xc * (-x * sin(i*M_PI / 180.0)); //投影
_y = -y * Zc +(-x * sin(i*M_PI / 180.0))*Yc;
SetPixel(hdcValue, 500 + int(_x * 20), 300 + int(_y * 20), RGB(102, 102, 102));
}
}
/*画壶体和壶盖(调用旋转投影turn函数)*/
void DrawCurve(float X[4], float Y[4], int n) {
turn(((X[0] + 3 * X[1] + 3 * X[2] + X[3]) / 8), ((Y[0] + 3 * Y[1] + 3 * Y[2] + Y[3]) / 8));
if (n > 0) {
n--;
float newXleft[4] = { X[0],(X[0] + X[1]) / 2,(X[0] + 2 * X[1] + X[2]) / 4,(X[0] + 3 * X[1] + 3 * X[2] + X[3]) / 8 };
float newYleft[4] = { Y[0],(Y[0] + Y[1]) / 2,(Y[0] + 2 * Y[1] + Y[2]) / 4,(Y[0] + 3 * Y[1] + 3 * Y[2] + Y[3]) / 8 };
float newXright[4] = { (X[0] + 3 * X[1] + 3 * X[2] + X[3]) / 8 ,(X[1] + 2 * X[2] + X[3]) / 4,(X[2] + X[3]) / 2,X[3] };
float newYright[4] = { (Y[0] + 3 * Y[1] + 3 * Y[2] + Y[3]) / 8 ,(Y[1] + 2 * Y[2] + Y[3]) / 4,(Y[2] + Y[3]) / 2,Y[3] };
DrawCurve(newXleft, newYleft, n);
DrawCurve(newXright, newYright, n);
}
}
int main(){
int n;
/*壶体旋转投影*/
n = 10;
for (int i = 0; i < 3; i++) {
float X[4] = { coe[i][0],coe[i][2],coe[i][4] ,coe[i][6] };
float Y[4] = { coe[i][1],coe[i][3],coe[i][5],coe[i][7] };
DrawCurve(X, Y, n);
}
n = 10;
for (int i = 0; i < 2; i++) {
float X[4] = { coe1[i][0],coe1[i][2],coe1[i][4] ,coe1[i][6] };
float Y[4] = { coe1[i][1],coe1[i][3],coe1[i][5],coe1[i][7] };
DrawCurve(X, Y, n);
}
trixmulSurface();
}
- Utah.h
#pragma once
/*壶体控制数据*/
float coe[3][8] = {
1.40000f,2.25000f,1.33750f,2.38125f,1.43750f,2.38125f,1.50000f,2.25000f,
1.50000f,2.25000f,1.75000f,1.72500f,2.00000f,1.20000f,2.00000f,0.75000f,
2.00000f,0.75000f,2.00000f,0.30000f,1.50000f,0.07500f,1.50000f,0.00000f
};
/*壶盖控制数据*/
float coe1[2][8] = {
0.00f,3.00f,0.80f,3.00f,0.00f,2.70f,0.20f,2.55f,
0.20f,2.55f,0.40f,2.40f,1.30f,2.40f,1.30f,2.25f
};
/*M矩阵*/
double M[4][4] = {
{ -1, 3,-3, 1 },
{ 3,-6, 3, 0 },
{ -3, 3, 0, 0 },
{ 1, 0, 0, 0 }
};
double _X[4][4][4] = {
{
/*壶嘴曲面参数1*/
{ 2.700,2.700,3.300,3.300 },
{ 2.800,2.800,3.525,3.525 },
{ 2.900,2.900,3.400,3.400 },
{ 2.800,2.800,3.200,3.200 }
},
{
/*壶嘴曲面参数2*/
{ 1.7,1.7,1.7,1.7 },
{ 2.6,2.6,3.1,3.1 },
{ 2.3,2.3,2.4,2.4 },
{ 2.7,2.7,3.3,3.3 }
},
{
/*把手曲面参数*/
{ 1.6,1.6,1.5,1.5 },
{ 2.3,2.3,2.5,2.5 },
{ 2.7,2.7,3.0,3.0 },
{ 2.7,2.7,3.0,3.0 }
},
{
/*把手曲面参数2*/
{ 2.70,2.70,3.00,3.00 },
{ 2.70,2.70,3.00,3.00 },
{ 2.50,2.50,2.65,2.65 },
{ 2.00,2.00,1.90,1.90 }
}
};
double _Y[4][4][4] = {
{
/*壶嘴曲面参数1*/
{ 2.25000,2.25000,2.20000,2.20000 },
{ 2.32500,2.32500,2.34375,2.34375 },
{ 2.32500,2.32500,2.36250,2.36250 },
{ 2.25000,2.25000,2.25000,2.25000 }
},
{
/*壶嘴曲面参数2*/
{ 1.270,1.270,0.400,0.400 },
{ 1.275,1.275,0.675,0.675 },
{ 1.950,1.950,1.875,1.875 },
{ 2.250,2.250,2.200,2.200 }
},
{
/*把手曲面参数*/
{ 1.875,1.875,2.1,2.1 },
{ 1.875,1.875,2.1,2.1 },
{ 1.875,1.875,2.1,2.1 },
{ 1.65,1.65,1.65,1.65 }
},
{
/*把手曲面参数2*/
{ 1.6500,1.6500,1.6500,1.6500 },
{ 1.4250,1.4250,1.2000,1.2000 },
{ 0.9750,0.9750,0.7875,0.7875 },
{ 0.7500,0.7500,0.4500,0.4500 }
}
};
double _Z[4][4][4] = {
{
/*壶嘴曲面参数1*/
{ 0.00,0.25,0.25,0.00 },
{ 0.00,0.25,0.25,0.00 },
{ 0.00,0.15,0.15,0.00 },
{ 0.00,0.15,0.15,0.00 }
},
{
/*壶嘴曲面参数2*/
{ 0.66,0,0.66,0 },
{ 0.66,0,0.66,0 },
{ 0.25,0,0.25,0 },
{ 0.25,0,0.25,0 }
},
{
/*把手曲面参数*/
{ 0.3,0,0.3,0 },
{ 0.3,0,0.3,0 },
{ 0.3,0,0.3,0 },
{ 0.3,0,0.3,0 }
},
{
/*把手曲面参数2*/
{ 0.3,0,0.3,0 },
{ 0.3,0,0.3,0 },
{ 0.3,0,0.3,0 },
{ 0.3,0,0.3,0 }
}
};