#include <iostream>
#include "Vector.h"
#include "Matrix.h"
#include "tinyxml2.h"
int main()
{
//坐标系O的基向量
Vector3 beta1(1.0f, 0.0f,0.0f);
Vector3 beta2(0.0f, 1.0f, 0.0f);
Vector3 beta3(0.0f, 0.0f, 1.0f);
//a点在坐标系O下的坐标
Vector3 aPosInO(100,25,36);
//以a点为原点构建坐标系A,以下三个基向量在坐标系O下的方向
Vector3 alpha1(0.8f, 0.1f, 0.0f);
Vector3 alpha2(0.1f, 0.9f, 0.0f);
Vector3 alpha3(0.0f, 0.2f, 0.75f);
//b点在坐标系A下的坐标值
Vector3 bPosInA(1,0,0);
//计算坐标系A到坐标系O的过渡矩阵
Matrix bMat;
bMat.SetIdentity();
bMat.m[0][0] = beta1.x; bMat.m[0][1] = beta2.x; bMat.m[0][2] = beta3.x;
bMat.m[1][0] = beta1.y; bMat.m[1][1] = beta2.y; bMat.m[1][2] = beta3.y;
bMat.m[2][0] = beta1.z; bMat.m[2][1] = beta2.z; bMat.m[2][2] = beta3.z;
Matrix aMat;
aMat.SetIdentity();
aMat.m[0][0] = alpha1.x; aMat.m[0][1] = alpha2.x; aMat.m[0][2] = alpha3.x;
aMat.m[1][0] = alpha1.y; aMat.m[1][1] = alpha2.y; aMat.m[1][2] = alpha3.y;
aMat.m[2][0] = alpha1.z; aMat.m[2][1] = alpha2.z; aMat.m[2][2] = alpha3.z;
// bMat = aMat * C;
//Inverse(aMat) * bMat = C;
Matrix C = aMat.Inverse() * bMat;
//[ax,ay,az] = C * [bx,by,bz];
// Inverse(C) * [ax,ay,az] = [bx,by,bz];
//
//利用过渡矩阵将b点变换到坐标系O下,由于是将坐标系A下的坐标值转换到坐标系O下,所以要用C的逆矩阵。
Vector3 bPosInOTemp = C.Inverse() * bPosInA;
//由于坐标系A的原点进行了平移,所以要加上偏移量
Vector3 bPosInO = bPosInOTemp + aPosInO;
//坐标系O下的c点坐标
Vector3 cPosInO(1.0f, 1.0f, 1.0f);
//坐标系O下的平面P上的一点p
Vector3 pPosInO(25.0f,30.0f, 35.0f);
//坐标系O下的平面P的法线n
Vector3 normalOfPlaneInO(1.0f,1.0f, 1.0f);
//以b为起点过c点的射线上的点可以表示为p = b + (c - b) * t,其中t为一个大于等于0的变量
//平面P上的任意一点可以表示为dot(n, (p - p0)) = 0,其中dot()表示向量的点积运算,p0为平面点法式中的已知的平面上的一点,n为平面法线
//联立两个方程得到t = [dot(n, p0) - dot(n, b)] / [dot(n, (c - b))]
float t = (Dot(normalOfPlaneInO, pPosInO) - Dot(normalOfPlaneInO, bPosInO)) / Dot(normalOfPlaneInO, (cPosInO - bPosInO));
//输出结果
bool bIntersect = false;
Vector3 posIntersect;
if (t >= 0.0f && t <= 1.0f)
{
bIntersect = true;
posIntersect = bPosInO + (cPosInO - bPosInO) * t;
}
std::cout << "b点在坐标系O下的坐标值是:( " << bPosInO.x << "," << bPosInO.y << "," << bPosInO.z << ")" << std::endl;
if (bIntersect)
{
std::cout << "b点和c点的连线与平面P的交点坐标值是:( " << posIntersect.x << "," << posIntersect.y << "," << posIntersect.z << ")" << std::endl;
}
else
{
std::cout << "b点和c点的连线与平面P无交点" << std::endl;
}
{
const char* szInitData = "<?xml version=\"1.0\" encoding=\"UTF - 8\" standalone=\"no\"?>";
tinyxml2::XMLDocument doc;
doc.Parse(szInitData);
tinyxml2::XMLElement* pInput = doc.NewElement("输入参数");
doc.InsertEndChild(pInput);
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("a点在坐标系O下的坐标值");
pDataElement->SetAttribute("X", aPosInO.x);
pDataElement->SetAttribute("Y", aPosInO.y);
pDataElement->SetAttribute("Z", aPosInO.z);
pInput->InsertEndChild(pDataElement);
}
{
tinyxml2::XMLElement* pDataElementBase = doc.NewElement("以a点为原点的坐标系A的基向量");
pInput->InsertEndChild(pDataElementBase);
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("坐标系A的基向量1");
pDataElement->SetAttribute("X", alpha1.x);
pDataElement->SetAttribute("Y", alpha1.y);
pDataElement->SetAttribute("Z", alpha1.z);
pDataElementBase->InsertEndChild(pDataElement);
}
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("坐标系A的基向量2");
pDataElement->SetAttribute("X", alpha2.x);
pDataElement->SetAttribute("Y", alpha2.y);
pDataElement->SetAttribute("Z", alpha2.z);
pDataElementBase->InsertEndChild(pDataElement);
}
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("坐标系A的基向量3");
pDataElement->SetAttribute("X", alpha3.x);
pDataElement->SetAttribute("Y", alpha3.y);
pDataElement->SetAttribute("Z", alpha3.z);
pDataElementBase->InsertEndChild(pDataElement);
}
}
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("b点在坐标系A下的坐标值");
pDataElement->SetAttribute("X", bPosInA.x);
pDataElement->SetAttribute("Y", bPosInA.y);
pDataElement->SetAttribute("Z", bPosInA.z);
pInput->InsertEndChild(pDataElement);
}
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("c点在坐标系O下的坐标值");
pDataElement->SetAttribute("X", cPosInO.x);
pDataElement->SetAttribute("Y", cPosInO.y);
pDataElement->SetAttribute("Z", cPosInO.z);
pInput->InsertEndChild(pDataElement);
}
{
tinyxml2::XMLElement* pDataElementBase = doc.NewElement("坐标系O下的平面P");
pInput->InsertEndChild(pDataElementBase);
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("平面P上的一点p的坐标");
pDataElement->SetAttribute("X", pPosInO.x);
pDataElement->SetAttribute("Y", pPosInO.y);
pDataElement->SetAttribute("Z", pPosInO.z);
pDataElementBase->InsertEndChild(pDataElement);
}
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("平面P的法线值");
pDataElement->SetAttribute("X", normalOfPlaneInO.x);
pDataElement->SetAttribute("Y", normalOfPlaneInO.y);
pDataElement->SetAttribute("Z", normalOfPlaneInO.z);
pDataElementBase->InsertEndChild(pDataElement);
}
}
tinyxml2::XMLElement* pOutput = doc.NewElement("输出结果");
doc.InsertEndChild(pOutput);
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("b点在坐标系O下的坐标值");
pDataElement->SetAttribute("X", bPosInO.x);
pDataElement->SetAttribute("Y", bPosInO.y);
pDataElement->SetAttribute("Z", bPosInO.z);
pOutput->InsertEndChild(pDataElement);
}
if (bIntersect)
{
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("b点和c点的连线与平面P的交点坐标值");
pDataElement->SetAttribute("X", posIntersect.x);
pDataElement->SetAttribute("Y", posIntersect.y);
pDataElement->SetAttribute("Z", posIntersect.z);
pOutput->InsertEndChild(pDataElement);
}
}
else
{
{
tinyxml2::XMLElement* pDataElement = doc.NewElement("b点和c点的连线与平面P无交点");
pOutput->InsertEndChild(pDataElement);
}
}
std::string strFilePath ="D:\\result.xml";
tinyxml2::XMLError errorCode = doc.SaveFile(strFilePath.c_str());
if (errorCode == tinyxml2::XML_SUCCESS)
{
std::cout << "程序运行结果保存在:" << strFilePath << "中。" << std::endl;
}
else
{
std::cout << "xml文件保存失败,错误码:" << errorCode << std::endl;
}
}
char c;
std::cin >> c;
return 0;
}