Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторные работы3 / KG3 / spatial
.cpp//---------------------------------------------------------------------------
#pragma hdrstop
#include "spatial.h"
Tspatial::Tspatial(TCanvas* tempc)
{
canva=tempc;
proection=ORT;
}
//---------------------------------------------------------------------------
void Tspatial::setParams(float oX, float oY, float temp_lengthos, float temp_alpha)
{
O.x=oX;
O.y=oY;
lengthOS=temp_lengthos;
alpha=temp_alpha;
//Прямая не паралельна плоскости
isExistCrossPoint = false;
isCrossLines = false;
isFrontal = false;
E = 0;
//Углы поворота вокруг осей
angleX = 0;
angleY = 0;
//angleZ = 0;
//Координаты наблюдателя
Camera.x = 50;
Camera.y = 50;
Camera.z = 100;
CameraReal = Camera;
//Устанавливаем координаты точек
A.x = 0;
A.y = 80;
A.z = 0;
AReal = A;
B.x = 50;
B.y = 0;
B.z = 0;
BReal = B;
C.x = 0;
C.y = 0;
C.z = 50;
CReal = C;
M.x = 0;
M.y = 60;
M.z = 0;
MReal = M;
N.x = 60;
N.y = 0;
N.z = 0;
NReal = N;
}
void Tspatial::change()
{
changeAngle(Form1->TrackBar4->Position, Form1->TrackBar5->Position, Form1->TrackBar6->Position);
if (Form1->RadioButton1->Checked)
changeProection(ORT);
else if (Form1->RadioButton2->Checked)
changeProection(PERSPECT);
calculate();
//Form1->setT(TReal.x, TReal.y, TReal.z);
draw();
}
void Tspatial::changeAngle (int x, int y, int z)
{
Camera.x = x;
Camera.y = y;
Camera.z = z;
if (sqrt(Camera.x*Camera.x + Camera.z*Camera.z))
angleY = acos((float)((float)Camera.z/(float)sqrt(Camera.x*Camera.x + Camera.z*Camera.z)));
//else if (Camera.x==0) angleY = 90/(float)((float)180.0f/(float)M_PI);
else angleY=0;
if (sqrt(Camera.x*Camera.x + Camera.y*Camera.y + Camera.z*Camera.z))
angleX = asin((float)((float)Camera.y/(float)sqrt(Camera.x*Camera.x + Camera.y*Camera.y + Camera.z*Camera.z)));
else
angleX = -90;
angleY = -angleY*(float)((float)180.0f/(float)M_PI);
angleX = angleX*(float)((float)180.0f/(float)M_PI);
}
void Tspatial::changePoint (int x, int y, int z)
{
//P.x=(float)x;
//P.y=(float)y;
//P.z=(float)z;
}
void Tspatial::changeProection (char type)
{
proection=type;
}
void Tspatial::calculate()
{
if (Camera.x==0&&Camera.y==0&&Camera.z==0)
{
status=CAMERA_NULL;
return;
}
status=GOOD;
//Задаем коодинаты осей
//Ось Х
XBegin.x = lengthOS;
XBegin.y = 0;
XBegin.z = 0;
XEnd.x = -lengthOS;
XEnd.y = 0;
XEnd.z = 0;
//Ось Y
YBegin.x = 0;
YBegin.y = lengthOS;
YBegin.z = 0;
YEnd.x = 0;
YEnd.y = -lengthOS;
YEnd.z = 0;
//Ось Z
ZBegin.x = 0;
ZBegin.y = 0;
ZBegin.z = lengthOS;
ZEnd.x = 0;
ZEnd.y = 0;
ZEnd.z = -lengthOS;
//Нахождение коэффициентов плоскости
findK();
findCrossPoint();
//Поворот вокруг оси Х
//Задаем матрицу поворота
float a[4][4] = {{1, 0, 0, 0},
{0, cos(radian(angleX)), sin(radian(angleX)), 0},
{0, -sin(radian(angleX)), cos(radian(angleX)), 0},
{0, 0, 0, 1}};
TMatrix Rx(4, 4, *a);
//Поворот вокруг оси У
float a2[4][4] = {{cos(radian(angleY)), 0, -sin(radian(angleY)), 0},
{0, 1, 0, 0},
{sin(radian(angleY)), 0, cos(radian(angleY)), 0},
{0, 0, 0, 1}};
TMatrix Ry(4, 4, *a2);
if (proection==ORT)
{
A = AReal*Ry*Rx;
B = BReal*Ry*Rx;
C = CReal*Ry*Rx;
M = MReal*Ry*Rx;
N = NReal*Ry*Rx;
T = TReal*Ry*Rx;
}
else if(proection==PERSPECT)
{
//Проверим, не находится ли камера внутри
/*if (P.x>=C.x&&P.y>=C.y&&P.z>=C.z)
{
status=CAMERA_IN;
return;
}*/
float koren = sqrt(Camera.x*Camera.x + Camera.y*Camera.y +Camera.z*Camera.z);
if (koren == 0)
koren = 1;
//Матрица перспективы
float pers[4][4] = {{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 0, -(float)1/(float)koren},
{0, 0, 0, 1}};
TMatrix persMatrix(4, 4, *pers);
A = AReal*Ry*Rx*persMatrix;
B = BReal*Ry*Rx*persMatrix;
C = CReal*Ry*Rx*persMatrix;
M = MReal*Ry*Rx*persMatrix;
N = NReal*Ry*Rx*persMatrix;
T = TReal*Ry*Rx*persMatrix;
// Проверим линии на выход за границы
if (ifLineOut())
{
status=LINE_OUT;
return;
}
}
XBegin = XBegin*Ry*Rx;
XEnd = XEnd*Ry*Rx;
YBegin = YBegin*Ry*Rx;
YEnd = YEnd*Ry*Rx;
ZBegin = ZBegin*Ry*Rx;
ZEnd = ZEnd*Ry*Rx;
}
void Tspatial::draw()
{
//Зачистим область
TRect r;
r.Left = 0;
r.Top = 0;
r.Right = O.x*2;
r.Bottom = O.y*2;
canva->FillRect(r);
if (status==CAMERA_IN)
{
canva->TextOutA(O.x-50, O.y, "Камера внутри объекта");
return;
}
if (status==LINE_OUT)
{
canva->TextOutA(O.x-80, O.y, "Линии рисунка за пределами области ");
return;
}
if (status==CAMERA_NULL)
{
canva->TextOutA(O.x-80, O.y, "Невозможно построить изображение");
return;
}
//Оси
//Х
canva->Pen->Width=1;
canva->Pen->Style=PS_SOLID;
canva->Pen->Color=clBlue;
canva->MoveTo(convert(XBegin).x, convert(XBegin).y);
canva->LineTo(O.x, O.y);
canva->Pen->Style=PS_DASH;
canva->LineTo(convert(XEnd).x, convert(XEnd).y);
//Y
canva->Pen->Style=PS_SOLID;
canva->Pen->Color=clGreen;
canva->MoveTo(convert(YBegin).x, convert(YBegin).y);
canva->LineTo(O.x, O.y);
canva->Pen->Style=PS_DASH;
canva->LineTo(convert(YEnd).x, convert(YEnd).y);
//Z
canva->Pen->Style=PS_SOLID;
canva->Pen->Color=clRed;
canva->MoveTo(convert(ZBegin).x, convert(ZBegin).y);
canva->LineTo(O.x, O.y);
canva->Pen->Style=PS_DASH;
canva->LineTo(convert(ZEnd).x, convert(ZEnd).y);
canva->Pen->Color=clBlack;
canva->Pen->Style=PS_SOLID;
//Подписываем оси
TextOut (canva->Handle, convert(XBegin).x-indentx, convert(XBegin).y-indenty, "X", 1);
TextOut (canva->Handle, convert(YBegin).x+indentx, convert(YBegin).y, "Y", 1);
TextOut (canva->Handle, convert(ZBegin).x+indentx, convert(ZBegin).y-indenty, "Z", 1);
//
canva->Pen->Width = 1;
canva->Pen->Color = (TColor)RGB(21, 183, 70);
//Рисуем линию из A в B
canva->MoveTo(convert(A).x, convert(A).y);
canva->LineTo(convert(B).x, convert(B).y);
//Рисуем линию из B в C
canva->MoveTo(convert(B).x, convert(B).y);
canva->LineTo(convert(C).x, convert(C).y);
//Рисуем линию из C в A
canva->MoveTo(convert(C).x, convert(C).y);
canva->LineTo(convert(A).x, convert(A).y);
//Делаем перо красным
canva->Pen->Color = (TColor)RGB(207, 22, 46);
//Рисуем линию из N в M
//если нет точки пересечения и прямая перед плоскостью или плоскость является фронт. проец, то рисуем сплошной линией
if ((!isExistCrossPoint && ScalM>E && ScalN>E) || isFrontal)
{
canva->Pen->Style=psSolid;
canva->MoveTo(convert(N).x, convert(N).y);
canva->LineTo(convert(M).x, convert(M).y);
}
//если нет точки пересечения и плоскость не фронт. проец. и прямая за плоскостью то рисуем пунктиром
if (!isExistCrossPoint && !isFrontal && ScalM<-E && ScalN<-E)
{
canva->Pen->Style=psDot;
canva->MoveTo(convert(N).x, convert(N).y);
canva->LineTo(convert(M).x, convert(M).y);
}
//Обе точки(отрезок) лежат(ит) на плоскости то рисуем сплошной. Также по этому условию срабатывает
//когда две прямые скрещиваются
if (!isExistCrossPoint && fabs(ScalM)<=E && fabs(ScalN)<=E)
{
canva->Pen->Style=psSolid;
canva->MoveTo(convert(N).x, convert(N).y);
canva->LineTo(convert(M).x, convert(M).y);
}
//если есть точка пересечения и плоскость не явл. фронт. проец. то рисуем с учетом видимости
if (isExistCrossPoint && !isFrontal)
{
//Точка М видима, а точка N невидима
if (ScalM > E && ScalN < -E)
{
canva->Pen->Style = psDot;
canva->MoveTo(convert(T).x, convert(T).y);
canva->LineTo(convert(N).x, convert(N).y);
canva->Pen->Style = psSolid;
canva->MoveTo(convert(T).x, convert(T).y);
canva->LineTo(convert(M).x, convert(M).y);
}
//Точка М невидима, а точка N видима
if (ScalM < -E && ScalN > E)
{
canva->Pen->Style = psDot;
canva->MoveTo(convert(T).x, convert(T).y);
canva->LineTo(convert(M).x, convert(M).y);
canva->Pen->Style = psSolid;
canva->MoveTo(convert(T).x, convert(T).y);
canva->LineTo(convert(N).x, convert(N).y);
}
//одна точка на плоскости, другая перед плоскостью
if ((fabs(ScalM)<=E && ScalN>E)||(fabs(ScalN)<=E && ScalM>E))
{
canva->Pen->Style = psSolid;
canva->MoveTo(convert(N).x, convert(N).y);
canva->LineTo(convert(M).x, convert(M).y);
}
//одна точка на плоскости, другая за плоскостью
if ((fabs(ScalM)<=E && ScalN<-E)||(fabs(ScalN)<=E && ScalM<-E))
{
canva->Pen->Style = psDot;
canva->MoveTo(convert(N).x, convert(N).y);
canva->LineTo(convert(M).x, convert(M).y);
}
//если идет пересечение прямых или плоскость-точка на прямой то рисуем сплошной
if (isCrossLines || isPlanePointOnLine)
{
canva->Pen->Style = psSolid;
canva->MoveTo(convert(N).x, convert(N).y);
canva->LineTo(convert(M).x, convert(M).y);
}
}
//Делаем перо черным
canva->Pen->Color = clBlack;
//и сплошным
canva->Pen->Style=psSolid;
//Рисуем точку A
canva->Ellipse(convert(A).x-3, convert(A).y-3, convert(A).x+3, convert(A).y+3);
//Рисуем точку B
canva->Ellipse(convert(B).x-3, convert(B).y-3, convert(B).x+3, convert(B).y+3);
//Рисуем точку C
canva->Ellipse(convert(C).x-3, convert(C).y-3, convert(C).x+3, convert(C).y+3);
//Рисуем точку N
canva->Ellipse(convert(N).x-3, convert(N).y-3, convert(N).x+3, convert(N).y+3);
//Рисуем точку M
canva->Ellipse(convert(M).x-3, convert(M).y-3, convert(M).x+3, convert(M).y+3);
if (isExistCrossPoint)
//Рисуем точку T
canva->Ellipse(convert(T).x-3, convert(T).y-3, convert(T).x+3, convert(T).y+3);
//Подписываем точку A
canva->TextOutA(convert(A).x+5, convert(A).y-18, "A");
//Подписываем точку B
canva->TextOutA(convert(B).x+5, convert(B).y-18, "B");
//Подписываем точку C
canva->TextOutA(convert(C).x+5, convert(C).y-18, "C");
//Подписываем точку N
canva->TextOutA(convert(N).x+5, convert(N).y-18, "N");
//Подписываем точку M
canva->TextOutA(convert(M).x+5, convert(M).y-18, "M");
if (isExistCrossPoint)
//Подписываем точку T
canva->TextOutA(convert(T).x+5, convert(T).y-18, "T");
}
point2D Tspatial::convert(point3D point)
{
point2D tempPoint;
tempPoint.x = O.x + point.x;
tempPoint.y = O.y - point.y;
return tempPoint;
}
float Tspatial::radian(float alpha)
{
return (float)((float)alpha*M_PI/(float)180.0f);
}
bool Tspatial::ifLineOut()
{
if (convert(A).x < 0 || convert(A).x > O.x*2 || convert(A).y < 0 || convert(A).y > O.y*2)
return true;
if (convert(B).x < 0 || convert(B).x > O.x*2 || convert(B).y < 0 || convert(B).y > O.y*2)
return true;
if (convert(C).x < 0 || convert(C).x > O.x*2 || convert(C).y < 0 || convert(C).y > O.y*2)
return true;
if (convert(M).x < 0 || convert(M).x > O.x*2 || convert(M).y < 0 || convert(M).y > O.y*2)
return true;
if (convert(N).x < 0 || convert(N).x > O.x*2 || convert(N).y < 0 || convert(N).y > O.y*2)
return true;
return false;
}
void Tspatial::setA(int valueX, int valueY, int valueZ)
{
AReal.x = valueX;
AReal.y = valueY;
AReal.z = valueZ;
}
void Tspatial::setB(int valueX, int valueY, int valueZ)
{
BReal.x = valueX;
BReal.y = valueY;
BReal.z = valueZ;
}
void Tspatial::setC(int valueX, int valueY, int valueZ)
{
CReal.x = valueX;
CReal.y = valueY;
CReal.z = valueZ;
}
void Tspatial::setN(int valueX, int valueY, int valueZ)
{
NReal.x = valueX;
NReal.y = valueY;
NReal.z = valueZ;
}
void Tspatial::setM(int valueX, int valueY, int valueZ)
{
MReal.x = valueX;
MReal.y = valueY;
MReal.z = valueZ;
}
point3D Tspatial::getA()
{
return AReal;
}
point3D Tspatial::getB()
{
return BReal;
}
point3D Tspatial::getC()
{
return CReal;
}
point3D Tspatial::getN()
{
return NReal;
}
point3D Tspatial::getM()
{
return MReal;
}
void Tspatial::SetE(int value)
{
E=value;
}
TPlaneType Tspatial::getPlaneType()
{
float k = E/10000;
//Плоскость является точкой
if (fabs(C.x-A.x)<=k && fabs(C.x-B.x)<=k && fabs(C.y-A.y)<=k && fabs(C.y-B.y)<=k && fabs(C.z-A.z)<=k && fabs(C.z-B.z)<=k)
{
Form1->LabelPlane->Caption = "Плоскость - точка";
return tpPoint;
}
//Плоскость является прямой
//Параметрическое уравнение прямой
float ur1=(CReal.x-AReal.x)*(BReal.y-AReal.y)-(CReal.y-AReal.y)*(BReal.x-AReal.x);
float ur2=(CReal.x-AReal.x)*(BReal.z-AReal.z)-(CReal.z-AReal.z)*(BReal.x-AReal.x);
float ur3=(CReal.y-AReal.y)*(BReal.z-AReal.z)-(CReal.z-AReal.z)*(BReal.y-AReal.y);
if (fabs(ur1) < E/100 && fabs(ur2) < E/100 && fabs(ur3) < E/100)
{
Form1->LabelPlane->Caption = "Плоскость - прямая";
return tpLine;
}
//Плоскость является плоскостью
Form1->LabelPlane->Caption = "Плоскость - плоскость";
return tpPlane;
}
TLineType Tspatial::getLineType()
{
float k = E/10000;
if(fabs(M.x-N.x) <= k && fabs(M.y-N.y) <= k && fabs(M.z-N.z) <= k)
{
Form1->LabelLine->Caption = "Отрезок - точка";
return tlPoint;
}
//Прямая является прямой
Form1->LabelLine->Caption = "Отрезок - отрезок";
return tlLine;
}
void Tspatial::findCrossPoint()
{
isExistCrossPoint = false;
isCrossLines = false;
isPlanePointOnLine = false;
//Скалярное произведение точек прямой на коэф. плоскости
ScalM = myltiplyPoint(MReal);
ScalN = myltiplyPoint(NReal);
//Узнаем типы прямой и плоскости
TPlaneType plType = getPlaneType();
TLineType lnType = getLineType();
//нет точки пересечения
if ((ScalM<-E && ScalN<-E) || (ScalM>E && ScalN>E))
{
Form1->LabelResult->Caption = "Нет точки перечения";
return;
}
//есть точка пересечения и плоскость является плоскостью а прямая прямой
if (((ScalM<-E && ScalN>E) || (ScalM>E && ScalN<-E)) && plType == tpPlane && lnType == tlLine)
{
isExistCrossPoint = true;
float t = getT();
TReal.x = NReal.x + t*(MReal.x - NReal.x);
TReal.y = NReal.y + t*(MReal.y - NReal.y);
TReal.z = NReal.z + t*(MReal.z - NReal.z);
Form1->LabelResult->Caption = "Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
}
//Точка М лежит на плоскости, которая имеет вид плоскости
if (fabs(ScalM)<=E && fabs(ScalN) > E && plType == tpPlane && lnType == tlLine)
{
isExistCrossPoint = true;
TReal.x = MReal.x;
TReal.y = MReal.y;
TReal.z = MReal.z;
Form1->LabelResult->Caption = "Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
}
//Точка N лежит на плоскости, которая имеет вид плоскости
if (fabs(ScalN)<=E && fabs(ScalM) > E && plType == tpPlane && lnType == tlLine)
{
isExistCrossPoint = true;
TReal.x = NReal.x;
TReal.y = NReal.y;
TReal.z = NReal.z;
Form1->LabelResult->Caption = "Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
}
//Прямая лежит на плоскости, которая имеет вид плоскости
if (fabs(ScalM)<=E && fabs(ScalN)<=E && plType == tpPlane && lnType == tlLine)
{
Form1->LabelResult->Caption = "Отрезок лежит на плоскости.";
}
//Прямая в виде точки лежит на плоскости
if (fabs(ScalM)<=E && plType == tpPlane && lnType == tlPoint)
{
isExistCrossPoint = true;
TReal.x = MReal.x;
TReal.y = MReal.y;
TReal.z = MReal.z;
Form1->LabelResult->Caption = "Прямая, в виде точки лежит на плоскости. Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
}
//Прямая в виде точки, плоскость в виде прямой
if (plType == tpLine && lnType == tlPoint)
{
//Подставляем прямую(точку) в уравнение
float ur1=(MReal.x-BReal.x)*(CReal.y-BReal.y)-(MReal.y-BReal.y)*(CReal.x-BReal.x);
float ur2=(MReal.x-BReal.x)*(CReal.z-BReal.z)-(MReal.z-BReal.z)*(CReal.x-BReal.x);
float ur3=(MReal.y-BReal.y)*(CReal.z-BReal.z)-(MReal.z-BReal.z)*(CReal.y-BReal.y);
float k = E/1000;
if(fabs(ur1)<=k && fabs(ur2)<=k && fabs(ur3)<=k)
{
isExistCrossPoint = true;
TReal.x = MReal.x;
TReal.y = MReal.y;
TReal.z = MReal.z;
Form1->LabelResult->Caption = "Прямая, в виде точки лежит на плоскости, которая имеет вид прямой. Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
}
else
Form1->LabelResult->Caption = "Прямая, в виде точки не принадлежит плоскости, которая имеет вид прямой";
}
//Прямая в виде прямой, а плоскость в виде точки
if (plType == tpPoint && lnType == tlLine)
{
//Алгоритм: точка принадлежит отрезку, если сумма растояний от концов отрезков до точки
//равна длине отрезка
//Расстояние от М до точки (плоскости)
float dist1 = sqrt((M.x-A.x)*(M.x-A.x) + (M.y-A.y)*(M.y-A.y) + (M.z-A.z)*(M.z-A.z));
//Расстояние от N до точки (плоскости)
float dist2 = sqrt((A.x-N.x)*(A.x-N.x) + (A.y-N.y)*(A.y-N.y) + (A.z-N.z)*(A.z-N.z));
//Длина отрезка MN
float dist3 = sqrt((M.x-N.x)*(M.x-N.x) + (M.y-N.y)*(M.y-N.y) + (M.z-N.z)*(M.z-N.z));
float k = E/1000;
if (fabs(dist1+dist2-dist3) <= k)
{
isExistCrossPoint = true;
isPlanePointOnLine = true;
TReal.x = AReal.x;
TReal.y = AReal.y;
TReal.z = AReal.z;
Form1->LabelResult->Caption = "Плоскость, в виде точки принадлежит прямой. Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
}
else
Form1->LabelResult->Caption = "Плоскость, в виде точки не принадлежит прямой.";
}
//Прямая в виде точки совпадает с плоскостью в виде точки
if (plType == tpPoint && lnType == tlPoint)
{
float k = E/1000;
if (fabs(M.x-A.x)<k && fabs(M.y-A.y)<k && fabs(M.z-A.z)<k)
{
isExistCrossPoint = true;
TReal.x = AReal.x;
TReal.y = AReal.y;
TReal.z = AReal.z;
Form1->LabelResult->Caption = "Прямая в виде точки совпадает с плоскостью (точкой). Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
}
else
Form1->LabelResult->Caption = "Прямая в виде точки не совпадает с плоскостью (точкой).";
}
//Плоскость в виде прямой и прямая в виде прямой
if (plType == tpLine && lnType == tlLine)
{
double x=0,y=0,z=0,xa1,xp1,ya1,yp1,za1,zp1,l1,l2,m1,m2,n1,n2;
//Плоскость-прямая у нас определяется с погрешностью поэтому за 2 точки
//плоскости-прямой берем точки расстояние между которыми наибольшее
double p1p2 = sqrt((AReal.x-BReal.x)*(AReal.x-BReal.x) + (AReal.y-BReal.y)*(AReal.y-BReal.y) + (AReal.z-BReal.z)*(AReal.z-BReal.z) );
double p1p3 = sqrt((AReal.x-CReal.x)*(AReal.x-CReal.x) + (AReal.y-CReal.y)*(AReal.y-CReal.y) + (AReal.z-CReal.z)*(AReal.z-CReal.z) );
double p2p3 = sqrt((BReal.x-CReal.x)*(BReal.x-CReal.x) + (BReal.y-CReal.y)*(BReal.y-CReal.y) + (BReal.z-CReal.z)*(BReal.z-CReal.z) );
if (p1p2>=p1p3 && p1p2>=p2p3)
{
xp1=AReal.x; l2=BReal.x-AReal.x;
yp1=AReal.y; m2=BReal.y-AReal.y;
zp1=AReal.z; n2=BReal.z-AReal.z;
}
if (p1p3>=p1p2 && p1p3>=p2p3)
{
xp1=AReal.x; l2=CReal.x-AReal.x;
yp1=AReal.y; m2=CReal.y-AReal.y;
zp1=AReal.z; n2=CReal.z-AReal.z;
}
if (p2p3>=p1p2&&p2p3>=p1p3)
{
xp1=BReal.x; l2=CReal.x-BReal.x;
yp1=BReal.y; m2=CReal.y-BReal.y;
zp1=BReal.z; n2=CReal.z-BReal.z;
}
xa1=MReal.x; ya1=MReal.y; za1=MReal.z;
l1=NReal.x-xa1; m1=NReal.y-ya1; n1=NReal.z-za1;
//определим лежат ли в одной плоскости
if(fabs((xp1-xa1)*m1*n2+(zp1-za1)*l1*m2+(yp1-ya1)*n1*l2-(zp1-za1)*m1*l2-(xp1-xa1)*n1*m2-(yp1-ya1)*l1*n2) <= E)
{
Form1->LabelResult->Caption = "Прямые лежат в одной плоскости.";
}
else
{
Form1->LabelResult->Caption = "Прямые скрещиваются!";
return;
}
//метод крамера
double ta=0;
double d1,d2,d3;//определители
d1 = -l1*m2 + l2*m1;
d2 = -l1*n2 + l2*n1;
d3 = -m1*n2 + m2*n1;
if(d1==0 && d2==0 && d3==0)
{
Form1->LabelResult->Caption = "Прямые параллельны или совпадают";
return;
}
if( d1!=0 )
{
ta = (-(xp1-xa1)*m2+l2*(yp1-ya1))/d1;
x=xa1+l1*ta;
y=ya1+m1*ta;
z=za1+n1*ta;
}
else if ( d2!=0 )
{
ta = (-n2*(xp1-xa1)+l2*(zp1-za1))/d2;
x=xa1+l1*ta;
y=ya1+m1*ta;
z=za1+n1*ta;
}
else if ( d3!=0 )
{
ta = (-n2*(yp1-ya1)+m2*(zp1-za1))/d3;
x=xa1+l1*ta;
y=ya1+m1*ta;
z=za1+n1*ta;
}
TReal.x = x;
TReal.y = y;
TReal.z = z;
//Мы нашли точку пересечения прямых. А Теперь нужно определить принадлежит ли точка пересечения отрезку [M N]
//Делается это так: Точка принадлежит отрезку, если сумма расстояний от этой точки до конечных точек отрезка равна длине отрезка
double a = sqrt((MReal.x-TReal.x)*(MReal.x-TReal.x) + (MReal.y-TReal.y)*(MReal.y-TReal.y) + (MReal.z-TReal.z)*(MReal.z-TReal.z) );//расстояние от M до точки пересечения
double b = sqrt((TReal.x-NReal.x)*(TReal.x-NReal.x) + (TReal.y-NReal.y)*(TReal.y-NReal.y) + (TReal.z-NReal.z)*(TReal.z-NReal.z) );//расстояние от точки пересечения до A2
double c = sqrt((MReal.x-NReal.x)*(MReal.x-NReal.x) + (MReal.y-NReal.y)*(MReal.y-NReal.y) + (MReal.z-NReal.z)*(MReal.z-NReal.z) );//расстояние от A1 до A2
float k = E/10000;
if(fabs(a+b-c) <= k)
{
isExistCrossPoint = true;
isCrossLines = true;
Form1->LabelResult->Caption = "Прямые пересекаются. Точка пересечения T("+IntToStr((int)TReal.x)+", "+IntToStr((int)TReal.y)+", "+IntToStr((int)TReal.z)+")";
return;
}
else
{
Form1->LabelResult->Caption = "Нет точки пересечения прямых.";
return;
}
}
}
float Tspatial::getT()
{
float t = -(float)(planeKoef.a*NReal.x + planeKoef.b*NReal.y + planeKoef.c*NReal.z + planeKoef.d)/(float)(planeKoef.a*(MReal.x-NReal.x) + planeKoef.b*(MReal.y-NReal.y) + planeKoef.c*(MReal.z-NReal.z));
return t;
}
float Tspatial::myltiplyPoint(point3D point, bool isCamera)
{
if (isCamera)
if (proection==PERSPECT)
return point.x*planeKoef.a + point.y*planeKoef.b + point.z*planeKoef.c + planeKoef.d;
else
return point.x*planeKoef.a + point.y*planeKoef.b + point.z*planeKoef.c;
else
return point.x*planeKoef.a + point.y*planeKoef.b + point.z*planeKoef.c + planeKoef.d;
}
void Tspatial::findK()
{
planeKoef.a = (AReal.y-BReal.y)*(AReal.z+BReal.z) + (BReal.y-CReal.y)*(BReal.z+CReal.z)+ (CReal.y-AReal.y)*(CReal.z+AReal.z);
planeKoef.b = (AReal.z-BReal.z)*(AReal.x+BReal.x) + (BReal.z-CReal.z)*(BReal.x+CReal.x)+ (CReal.z-AReal.z)*(CReal.x+AReal.x);
planeKoef.c = (AReal.x-BReal.x)*(AReal.y+BReal.y) + (BReal.x-CReal.x)*(BReal.y+CReal.y)+ (CReal.x-AReal.x)*(CReal.y+AReal.y);
planeKoef.d = -(planeKoef.a*AReal.x + planeKoef.b*AReal.y + planeKoef.c*AReal.z);
float value1 = -(planeKoef.a*AReal.x + planeKoef.b*AReal.y + planeKoef.c*AReal.z);
float value2 = -(planeKoef.a*BReal.x + planeKoef.b*BReal.y + planeKoef.c*BReal.z);
float value3 = -(planeKoef.a*CReal.x + planeKoef.b*CReal.y + planeKoef.c*CReal.z);
//Скалярное произведение точки наблюдателя на коэф. плоскости
float ScalCamera = myltiplyPoint(Camera, true);
if (ScalCamera < 0)
{
//Перенаправляем плоскость
planeKoef.a = -planeKoef.a;
planeKoef.b = -planeKoef.b;
planeKoef.c = -planeKoef.c;
planeKoef.d = -planeKoef.d;
}
isFrontal = false;
TPlaneType type = getPlaneType();
if (type == tpPlane && fabs(ScalCamera) < E)
isFrontal = true;
}
#pragma package(smart_init)