1369 lines
39 KiB
C++
1369 lines
39 KiB
C++
#include "StdAfx.h"
|
||
#include "dlwdmain.h"
|
||
//#include "afxdialogex.h"
|
||
#include "dbray.h"
|
||
#include "dbelipse.h"
|
||
|
||
static TBuildInfomationDlg *g_pDlg = NULL;
|
||
|
||
static AcDbObjectId g_idBuild = AcDbObjectId::kNull;
|
||
static AcDbObjectId g_idLight = AcDbObjectId::kNull;
|
||
|
||
namespace
|
||
{
|
||
void Poly2Building(AcDbObjectId id, const double lastH, const double elevH, LPCTSTR slayer)
|
||
{
|
||
ads_name name;
|
||
if (Acad::eOk != acdbGetAdsName(name, id)) return;
|
||
|
||
TEntitySet e(name);
|
||
PickSet ss(SS_FREE);
|
||
ss += e;
|
||
|
||
Entity entFirst = ss[0L];
|
||
double nElev(elevH), nHeight(lastH);
|
||
|
||
double nLastHeight = _AS_MM(nHeight);
|
||
|
||
Entity ent = ss[0L];
|
||
XPoint vtNorm(0, 0, 1);
|
||
|
||
ent.GetData(210, vtNorm);
|
||
if (vtNorm.AsAcGeVector3d() != AcGeVector3d(0, 0, 1))
|
||
{
|
||
adsout << _T("\n发现pline法向无效!");
|
||
return;
|
||
}
|
||
|
||
XPoly2D poly2d(ent);
|
||
poly2d.SetFlag(1);//强制封闭,add by whl on 060418
|
||
poly2d.Compress();
|
||
|
||
if (poly2d.IsSelfIntersect())
|
||
{
|
||
adsout << _T("\n发现自交的无效pline!");
|
||
return;
|
||
}
|
||
|
||
if (poly2d.PathArea() > 0.0)
|
||
poly2d.Reverse();
|
||
|
||
TDbSlab *pSlab = new TDbSlab;
|
||
pSlab->SetOutline(poly2d);
|
||
pSlab->SetElevation(nElev);
|
||
pSlab->SetThickness(nHeight);
|
||
pSlab->setLayer(slayer);
|
||
|
||
AcDbObjectId idNew = AddToModelSpace(pSlab, Adesk::kTrue);
|
||
}
|
||
|
||
int FindCloseLine(const std::vector<AcGeLineSeg3d> &lines, LPCTSTR str)
|
||
{
|
||
XPushVar<int> osmode(_T("OSMODE"), 0);
|
||
XPoint point;
|
||
double dist(.0);
|
||
std::map<double, int> lmap;
|
||
while (true)
|
||
{
|
||
lmap.clear();
|
||
|
||
int ret = acedGetPoint(NULL, str, point);
|
||
if (ret != RTNORM) return -1;
|
||
|
||
AcGePoint3d acgePt(point.x, point.y, point.z);
|
||
|
||
for (int i = 0; i < lines.size(); ++i)
|
||
lmap.insert(std::make_pair(lines[i].distanceTo(acgePt), i));
|
||
|
||
if (lmap.size() < lines.size()) // 说明与其它边的distance相同,重选
|
||
{
|
||
acutPrintf(_T("\n请重新选择!"));
|
||
continue;
|
||
}
|
||
return lmap.begin()->second;
|
||
}
|
||
}
|
||
|
||
void InsertText(LPCTSTR strText, const AcGePoint3d &ptDefault, const AcGeVector3d &vec)
|
||
{
|
||
XPoint point;
|
||
TDbText *pTextLabel = new TDbText();
|
||
pTextLabel->SetAlignment(XExplodeDraw::kLeft);
|
||
pTextLabel->SetPScale(1);
|
||
pTextLabel->SetStyleId(GetTextStyleId(_T("黑体")));
|
||
pTextLabel->SetHeight(9.11);
|
||
pTextLabel->SetLocation(ptDefault);
|
||
pTextLabel->SetText(strText);
|
||
pTextLabel->SetRotation(atan(vec.y/vec.x));
|
||
pTextLabel->setLayer(_T("总图-字体"));
|
||
AddToCurrentSpace(pTextLabel, Adesk::kTrue);
|
||
}
|
||
|
||
AcDbObjectId CreateHatchForObj(AcDbObjectIdArray &ids)
|
||
{
|
||
AcDbHatch *pHatch = new AcDbHatch;
|
||
Acad::ErrorStatus es =pHatch->setHatchObjectType(AcDbHatch::kHatchObject);
|
||
es = pHatch->setNormal(AcGeVector3d(0, 0, 1));
|
||
es = pHatch->setElevation(0.0);
|
||
es = pHatch->setAssociative(Adesk::kFalse);
|
||
es = pHatch->setHatchStyle(AcDbHatch::kNormal);
|
||
es = pHatch->setColorIndex(140);
|
||
es = pHatch->setPatternAngle(0.0);
|
||
es = pHatch->setPatternScale(1/*DocGetPScale()*/);
|
||
es = pHatch->setPattern(AcDbHatch::kPreDefined, _T("NET3"));
|
||
es = pHatch->insertLoopAt(0, AcDbHatch::kExternal, ids);
|
||
es = pHatch->evaluateHatch();
|
||
return AddToCurrentSpace(pHatch, Adesk::kTrue);
|
||
}
|
||
|
||
int Dim2Pt(XPoint ptLeft, XPoint ptRight)
|
||
{
|
||
if (ptRight.Distance2d(ptLeft) < _DIST_SNAP)
|
||
{
|
||
return FALSE;
|
||
}
|
||
TDbDimension2 *pDim = new TDbDimension2;
|
||
pDim->SetPScale(1);
|
||
pDim->SetLayoutRotation(Ucs2Wcs(0));//add by whl on 060306
|
||
pDim->SetLocation(ptLeft);
|
||
pDim->SetRotation(ads_angle(ptLeft, ptRight));
|
||
pDim->SetDist2DimLine(6.0, TRUE);
|
||
pDim->AppendSegment(ptLeft.Distance2d(ptRight));
|
||
AcDbObjectId idStyle = InitDimStyle(DS_LINEAR);
|
||
pDim->SetStyleId(idStyle);
|
||
|
||
AcGiTextStyle txtStyle;
|
||
OPENOBJ_BEGIN(idStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle);
|
||
ASSERT(pStyle);
|
||
VERIFY(fromAcDbTextStyle(txtStyle, pStyle->dimtxsty()) == Acad::eOk);
|
||
int nRetFlag = txtStyle.loadStyleRec();
|
||
txtStyle.setTextSize(pStyle->dimtxt()*pDim->GetPScale()*0.8);
|
||
OPENOBJ_END();
|
||
|
||
ads_real rHWidth = ads_distance(ptLeft, ptRight) / 2, rAngle = ads_angle(ptLeft, ptRight); //移动方向
|
||
AcGePoint2d ptExt = txtStyle.extents(pDim->GetText(0), Adesk::kTrue, -1, Adesk::kTrue);
|
||
rHWidth += ptExt[0] / 2 + 1.0*pDim->GetPScale();
|
||
XVector3D vtMove(rHWidth*cos(rAngle), rHWidth*sin(rAngle));
|
||
XPoint ptText = pDim->GetTextPos(0);
|
||
ptText += vtMove;
|
||
//pDim->SetTextPos(0, ptText);
|
||
|
||
pDim->SetLayoutRotation(Ucs2Wcs(0.0));
|
||
|
||
pDim->setLayer(_T("总图-尺寸标注"));
|
||
AddToModelSpace(pDim);
|
||
return RTNORM;
|
||
}
|
||
|
||
void DrawCircle(AcGePoint3d pt, int idxcolor = -1)
|
||
{
|
||
AcDbCircle *pCir = new AcDbCircle(pt, AcGeVector3d::kZAxis, 1);
|
||
if (idxcolor != -1)
|
||
pCir->setColorIndex(idxcolor);
|
||
AddToModelSpace(pCir);
|
||
}
|
||
|
||
void DrawLine(AcGeLineSeg3d line, int idxcolor = -1)
|
||
{
|
||
AcDbLine *pL = new AcDbLine(line.startPoint(), line.endPoint());
|
||
if (idxcolor != -1)
|
||
pL->setColorIndex(idxcolor);
|
||
AddToModelSpace(pL);
|
||
}
|
||
|
||
AcDbObjectId Insert2MSpace(TGGePoly3D &poly, LPCTSTR slayer)
|
||
{
|
||
AcDbObjectId id(AcDbObjectId::kNull);
|
||
AcDbCurve *p(NULL);
|
||
AcDbCurve *pC = poly.AsAcDbCurve();
|
||
pC->getOrthoProjectedCurve(AcGePlane::kXYPlane, p);
|
||
if (p)
|
||
{
|
||
p->setLayer(slayer);
|
||
id = AddToModelSpace(p);
|
||
}
|
||
delete pC;
|
||
return id;
|
||
}
|
||
}
|
||
|
||
void WD()
|
||
{
|
||
if (g_pDlg)
|
||
{
|
||
g_pDlg->DestroyWindow();
|
||
g_pDlg = NULL;
|
||
}
|
||
else
|
||
{
|
||
CAcModuleResourceOverride res;
|
||
g_pDlg = new TBuildInfomationDlg;
|
||
g_pDlg->Create(IDD_DIALOG_DLWD, (CWnd*)acedGetAcadFrame());
|
||
g_pDlg->ShowWindow(SW_SHOW);
|
||
g_pDlg->CenterWindow();
|
||
}
|
||
}
|
||
|
||
void WDLG()
|
||
{
|
||
if (!g_idBuild.isValid() || !g_idLight.isValid()) return;
|
||
|
||
Poly2Building(g_idBuild, 15.9, 0., _T("总图-建筑轮廓线"));
|
||
Poly2Building(g_idLight, 26.1, 0., _T("轻资产"));
|
||
|
||
acedPostCommand(_T("-view _swiso "));
|
||
acedPostCommand(_T("_SHADEMODE r "));
|
||
};
|
||
|
||
// dlwdmain.cpp : implementation file
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
namespace
|
||
{
|
||
void EnableCtrl(CDialog *pDlg, int resid, BOOL bDisable)
|
||
{
|
||
if (!pDlg) return;
|
||
CWnd *pWnd = pDlg->GetDlgItem(resid);
|
||
if (!pWnd) return;
|
||
pWnd->EnableWindow(bDisable);
|
||
}
|
||
|
||
void VisableCtrl(CDialog *pDlg, int resid, int nshow)
|
||
{
|
||
if (!pDlg) return;
|
||
CWnd *pWnd = pDlg->GetDlgItem(resid);
|
||
if (!pWnd) return;
|
||
pWnd->ShowWindow(nshow);
|
||
}
|
||
}
|
||
|
||
IMPLEMENT_DYNAMIC(TBuildInfomationDlg, CModelessDialog)
|
||
|
||
TBuildInfomationDlg::TBuildInfomationDlg(CWnd* pParent /*=NULL*/)
|
||
: CModelessDialog(TBuildInfomationDlg::IDD, pParent) { }
|
||
|
||
TBuildInfomationDlg::~TBuildInfomationDlg()
|
||
{
|
||
RemoveColorLine();
|
||
}
|
||
|
||
void TBuildInfomationDlg::DoDataExchange(CDataExchange* pDX)
|
||
{
|
||
CDialog::DoDataExchange(pDX);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_UP_AOTO, m_redline.m_nUpAtuoNum);
|
||
DDV_MinMaxInt(pDX, m_redline.m_nUpAtuoNum, 0, 100000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_UP_BIKE, m_redline.m_nUpBikeNum);
|
||
DDV_MinMaxInt(pDX, m_redline.m_nUpBikeNum, 0, 100000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_GREEN_RATIO , m_redline.m_dGreen);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dGreen, 0, 100);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_BUILD_DENSITY, m_redline.m_dBuildDensity);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBuildDensity, 0, 100);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_UP_BUILD_AREA, m_redline.m_dUpBuildArea);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dUpBuildArea, 0, 990000000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_DOWN_BUILD_AREA, m_redline.m_dDownBuildArea);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dDownBuildArea, 0, 990000000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_RED, m_redline.m_dBacklineRed);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineRed, 0, 1000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_YELLOW, m_redline.m_dBacklineYellow);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineYellow, 0, 1000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_GREEN, m_redline.m_dBacklineGreen);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineGreen, 0, 1000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_CYAN, m_redline.m_dBacklineCyan);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineCyan, 0, 1000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_BLUE, m_redline.m_dBacklineBlue);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineBlue, 0, 1000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_MAGENTA, m_redline.m_dBacklineMagenta);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineMagenta, 0, 1000);
|
||
|
||
DDX_Text(pDX, IDC_EDIT_WHITE, m_redline.m_dBacklineWhite);
|
||
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineWhite, 0, 1000);
|
||
}
|
||
|
||
|
||
BEGIN_MESSAGE_MAP(TBuildInfomationDlg, CModelessDialog)
|
||
ON_BN_CLICKED(IDC_BUTTON_SELECT, &TBuildInfomationDlg::OnBnClickedButtonSelect)
|
||
ON_BN_CLICKED(IDC_BUTTON_CALC, &TBuildInfomationDlg::OnBnClickedButtonCalc)
|
||
ON_WM_CTLCOLOR()
|
||
ON_WM_CLOSE()
|
||
ON_WM_DESTROY()
|
||
ON_EN_CHANGE(IDC_EDIT_UP_AOTO, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_UP_BIKE, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_GREEN_RATIO, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_BUILD_DENSITY, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_UP_BUILD_AREA, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_DOWN_BUILD_AREA, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_RED, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_YELLOW, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_GREEN, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_CYAN, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_BLUE, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_MAGENTA, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_EN_CHANGE(IDC_EDIT_WHITE, &TBuildInfomationDlg::OnEnKillfocusEdit)
|
||
ON_MESSAGE(WM_ACAD_KEEPFOCUS, &TBuildInfomationDlg::OnAcadKeepFocus)
|
||
END_MESSAGE_MAP()
|
||
|
||
BOOL TBuildInfomationDlg::OnInitDialog()
|
||
{
|
||
CDialog::OnInitDialog();
|
||
|
||
SetWindowText(_T("上华软件"));
|
||
|
||
BeforSelectRedline();
|
||
|
||
UpdateData(FALSE);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void TBuildInfomationDlg::OnBnClickedButtonSelect()
|
||
{
|
||
ShowWindow(SW_HIDE);
|
||
EnableCtrl(this, IDC_BUTTON_SELECT, FALSE);
|
||
|
||
RBList mask(RTDXF0, _T("POLYLINE,LWPOLYLINE"), NULL);
|
||
XPoint ptPick;
|
||
TEntitySet ent;
|
||
XPoint point;
|
||
AcGeLineSeg3d seg, seg2, seg1;
|
||
AcGePoint3d pt, pt1, pt2;
|
||
AcDbObjectId id;
|
||
TDocLock lock;
|
||
|
||
long iResult = ent.FilterSelect(_T("\n请选择红线<取消>:"), mask, ptPick);
|
||
if (iResult != RTNORM) goto failed;
|
||
if (Acad::eOk != acdbGetObjectId(m_redline.m_id, ent)) goto failed;
|
||
|
||
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AcDbPolyline, pPoly);
|
||
{
|
||
if (pPoly == NULL || pPoly->numVerts() < 3 || pPoly->numVerts() > 7)
|
||
{
|
||
AfxMessageBox(_T("请选择大于3并小于8结点的pline线。"));
|
||
goto failed;
|
||
}
|
||
|
||
m_redline.m_RedlinePoly.SetAcDbCurve(pPoly);
|
||
|
||
//把多段线分段保存在List中
|
||
AcGeLineSeg3d lineSeg;
|
||
for (size_t i = 0; i < pPoly->numVerts(); ++i)
|
||
{
|
||
if (Acad::eOk == pPoly->getLineSegAt((int)i, lineSeg))
|
||
m_redline.m_RedSegs.push_back(lineSeg);
|
||
}
|
||
|
||
//计算面积
|
||
if (Acad::eOk != pPoly->getArea(m_redline.m_dRedlineArea))
|
||
{
|
||
AfxMessageBox(_T("\n取得PLINE线面积失败。"));
|
||
goto failed;
|
||
}
|
||
|
||
pPoly->setVisibility(AcDb::kInvisible);
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
|
||
// 涂颜色
|
||
for (size_t i = 0; i < m_redline.m_RedSegs.size(); ++i)
|
||
{
|
||
if (i > 7) break;
|
||
AcDbLine *pLine = new AcDbLine(m_redline.m_RedSegs[i].startPoint(), m_redline.m_RedSegs[i].endPoint());
|
||
pLine->setColorIndex((int)(i+1));
|
||
m_redline.m_colorLines.push_back(AddToModelSpace(pLine));
|
||
}
|
||
|
||
m_redline.m_idxDirect = FindCloseLine(m_redline.m_RedSegs, _T("\n请选择建筑物方向:"));
|
||
if (m_redline.m_idxDirect == -1) goto failed;
|
||
seg1 = m_redline.m_RedSegs[m_redline.m_idxDirect];
|
||
pt1 = seg1.midPoint();
|
||
AcDbCircle *pCir = new AcDbCircle(pt1, AcGeVector3d::kZAxis, seg1.length()*.05);
|
||
pCir->setColorIndex(m_redline.m_idxDirect + 1);
|
||
m_redline.m_colorLines.push_back(AddToModelSpace(pCir));
|
||
|
||
//选择建筑物靠近的边
|
||
do
|
||
{
|
||
m_redline.m_idxCloses = FindCloseLine(m_redline.m_RedSegs, _T("\n请选择建筑物靠近的边:"));
|
||
if (m_redline.m_idxCloses == -1) return;
|
||
seg2 = m_redline.m_RedSegs[m_redline.m_idxCloses];
|
||
// 判断选取的两根线是否有交点
|
||
if (seg1.intersectWith(seg2, pt) != Adesk::kTrue) // 没有交点,则重选idx2
|
||
{
|
||
AfxMessageBox(_T("\n请选择相邻的边。"));
|
||
continue;
|
||
}
|
||
break;
|
||
} while (true);
|
||
|
||
// 取出与方向边相邻的另一条边的索引
|
||
seg1 = m_redline.m_RedSegs[m_redline.m_idxDirect];
|
||
seg2 = m_redline.m_RedSegs[m_redline.m_idxCloses];
|
||
for (size_t i = 0; i < m_redline.m_RedSegs.size(); ++i)
|
||
{
|
||
seg = m_redline.m_RedSegs[i];
|
||
if (seg == seg1 || seg == seg2)continue;
|
||
if (seg.intersectWith(seg1, pt))
|
||
{
|
||
m_redline.m_idxOther = (int)i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
pt2 = seg2.midPoint();
|
||
pCir = new AcDbCircle(pt2, AcGeVector3d::kZAxis, seg1.length()*.05);
|
||
pCir->setColorIndex(m_redline.m_idxCloses + 1);
|
||
m_redline.m_colorLines.push_back(AddToModelSpace(pCir));
|
||
|
||
AfterSelectRedline();
|
||
ShowWindow(SW_SHOW);
|
||
return;
|
||
|
||
failed:
|
||
EnableCtrl(this, IDC_BUTTON_SELECT, TRUE);
|
||
ShowWindow(SW_SHOW);
|
||
m_redline.m_id = AcDbObjectId::kNull;
|
||
}
|
||
|
||
void TBuildInfomationDlg::OnBnClickedButtonCalc()
|
||
{
|
||
UpdateData(TRUE);
|
||
if (!m_redline.m_id.isValid()) return;
|
||
TDocLock lock;
|
||
OPENOBJ_BEGIN(m_redline.m_id, AcDb::kForWrite, AcDbPolyline, pPoly)
|
||
{
|
||
if (pPoly)
|
||
pPoly->setVisibility(AcDb::kVisible);
|
||
}
|
||
OPENOBJ_END()
|
||
|
||
EnableCtrl(this, IDC_BUTTON_SELECT, TRUE);
|
||
RemoveColorLine();
|
||
UpdateData(TRUE);
|
||
m_redline.CalcBackLine();
|
||
|
||
AcGeLineSeg3d segBLDirect(m_redline.GetBLDirectSeg()),
|
||
segBLCloses(m_redline.GetBLClosesSeg()),
|
||
segBLOther(m_redline.GetBLOtherSeg());
|
||
|
||
// 计算出 m_ptCloses 与 m_ptOther 两点
|
||
segBLDirect.intersectWith(segBLCloses, m_redline.m_ptCloses);
|
||
m_redline.m_ptOther = m_redline.m_ptCloses == segBLDirect.startPoint() ? segBLDirect.endPoint() : segBLDirect.startPoint();
|
||
|
||
// 计算出 m_vtDirect, m_vtOther, m_vtCloses
|
||
m_redline.m_vtDirect = m_redline.m_ptOther - m_redline.m_ptCloses;
|
||
m_redline.m_vtCloses = (m_redline.m_ptCloses == segBLCloses.startPoint() ? segBLCloses.endPoint() : segBLCloses.startPoint()) - m_redline.m_ptCloses;
|
||
m_redline.m_vtOther = (m_redline.m_ptOther == segBLOther.startPoint() ? segBLOther.endPoint() : segBLOther.startPoint()) - m_redline.m_ptOther;
|
||
|
||
|
||
double dMin = m_redline.CalcNo3Step();
|
||
CString strArea(_T(""));
|
||
strArea.Format(_T("%.2f万平方米"), (m_redline.m_dUpBuildArea + m_redline.m_dDownBuildArea)*.0001);
|
||
GetDlgItem(IDC_STATIC_ALL_AREA)->SetWindowText(strArea);
|
||
|
||
strArea.Format(_T("%.2f"), m_redline.m_dVolume);
|
||
GetDlgItem(IDC_STATIC_VOLUME)->SetWindowText(strArea);
|
||
|
||
if (dMin > 28000)
|
||
{
|
||
m_redline.m_b3Floor = true;
|
||
GetDlgItem(IDC_STATIC_RESULT)->SetWindowText(_T("采用三层街方案"));
|
||
}
|
||
else
|
||
{
|
||
m_redline.m_b3Floor = false;
|
||
GetDlgItem(IDC_STATIC_RESULT)->SetWindowText(_T("采用四层街方案"));
|
||
}
|
||
|
||
bool bRel = m_redline.CalcNo4Step();
|
||
|
||
if (bRel)
|
||
m_redline.CalcDim();
|
||
|
||
AcGePoint3d ptIns;
|
||
{// 计算用地面积插入点
|
||
AcGeRay3d ray(m_redline.m_ptOther, m_redline.m_vtOther);
|
||
for (size_t i = 0; i < m_redline.m_RedSegs.size(); ++i)
|
||
{
|
||
AcGeLineSeg3d &seg = m_redline.m_RedSegs[i];
|
||
if (ray.intersectWith(seg, ptIns))
|
||
break;
|
||
}
|
||
}
|
||
|
||
CString strText;
|
||
strText.Format(_T("用地面积%.2f万平方米,合%.2f亩"), m_redline.m_dRedlineArea*.0001, m_redline.m_dRedlineArea*0.0015);
|
||
InsertText(strText, ptIns, m_redline.m_vtDirect);
|
||
|
||
strText.Format(_T("室内街 %s L=%.2fm"), m_redline.m_b3Floor ? _T("3F") : _T("4F"), m_redline.m_dFootLength);
|
||
InsertText(strText, m_redline.m_ptInsertFootDim, m_redline.m_vtDirect);
|
||
|
||
strText.Format(_T("轻资产(%.0f万+%.0f万)"), m_redline.m_dUpBuildArea*.0001, m_redline.m_dDownBuildArea*.0001);
|
||
InsertText(strText, m_redline.m_ptInsertLightDim1, m_redline.m_vtDirect);
|
||
strText = _T("5F");
|
||
InsertText(strText, m_redline.m_ptInsertLightDim2, m_redline.m_vtDirect);
|
||
|
||
acedPostCommand(_T("re\n"));
|
||
|
||
EnableCtrl(this, IDC_BUTTON_CALC, FALSE);
|
||
}
|
||
|
||
void TBuildInfomationDlg::ShowBackLineCtrl()
|
||
{
|
||
int n = (int)m_redline.m_RedSegs.size();
|
||
if (n > 6) //7
|
||
{
|
||
VisableCtrl(this, IDC_EDIT_WHITE, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_WHITE, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_WHITE_M, TRUE);
|
||
}
|
||
if (n > 5) // 6
|
||
{
|
||
VisableCtrl(this, IDC_EDIT_MAGENTA, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_MAGENTA, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_MAGENTA_M, TRUE);
|
||
|
||
}
|
||
if (n> 4) // 5
|
||
{
|
||
VisableCtrl(this, IDC_EDIT_BLUE, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_BLUE, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_BLUE_M, TRUE);
|
||
|
||
}
|
||
if (n > 3) // 4
|
||
{
|
||
VisableCtrl(this, IDC_EDIT_CYAN, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_CYAN, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_CYAN_M, TRUE);
|
||
|
||
}
|
||
if (n > 2) // 3
|
||
{
|
||
VisableCtrl(this, IDC_EDIT_RED, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_RED, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_RED_M, TRUE);
|
||
VisableCtrl(this, IDC_EDIT_YELLOW, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_YELLOW, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_YELLOW_M, TRUE);
|
||
VisableCtrl(this, IDC_EDIT_GREEN, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_GREEN, TRUE);
|
||
VisableCtrl(this, IDC_STATIC_GREEN_M, TRUE);
|
||
}
|
||
}
|
||
|
||
void TBuildInfomationDlg::OnDestroy()
|
||
{
|
||
g_pDlg = NULL;
|
||
CModelessDialog::OnDestroy();
|
||
delete this;
|
||
}
|
||
|
||
void TBuildInfomationDlg::OnClose()
|
||
{
|
||
acedPostCommand(_T("\33\33"));
|
||
DestroyWindow();
|
||
}
|
||
|
||
void TBuildInfomationDlg::BeforSelectRedline()
|
||
{
|
||
// 没有选中红线之前,所有控件为灰
|
||
EnableCtrl(this, IDC_EDIT_UP_AOTO, FALSE);
|
||
EnableCtrl(this, IDC_EDIT_UP_BIKE, FALSE);
|
||
EnableCtrl(this, IDC_EDIT_GREEN_RATIO, FALSE);
|
||
EnableCtrl(this, IDC_EDIT_BUILD_DENSITY, FALSE);
|
||
EnableCtrl(this, IDC_EDIT_UP_BUILD_AREA, FALSE);
|
||
EnableCtrl(this, IDC_EDIT_DOWN_BUILD_AREA, FALSE);
|
||
EnableCtrl(this, IDC_BUTTON_CALC, FALSE);
|
||
|
||
VisableCtrl(this, IDC_EDIT_RED, FALSE);
|
||
VisableCtrl(this, IDC_EDIT_YELLOW, FALSE);
|
||
VisableCtrl(this, IDC_EDIT_GREEN, FALSE);
|
||
VisableCtrl(this, IDC_EDIT_CYAN, FALSE);
|
||
VisableCtrl(this, IDC_EDIT_BLUE, FALSE);
|
||
VisableCtrl(this, IDC_EDIT_MAGENTA, FALSE);
|
||
VisableCtrl(this, IDC_EDIT_WHITE, FALSE);
|
||
|
||
VisableCtrl(this, IDC_STATIC_RED, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_YELLOW, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_GREEN, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_CYAN, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_BLUE, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_MAGENTA, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_WHITE, FALSE);
|
||
|
||
VisableCtrl(this, IDC_STATIC_RED_M, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_YELLOW_M, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_GREEN_M, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_CYAN_M, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_BLUE_M, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_MAGENTA_M, FALSE);
|
||
VisableCtrl(this, IDC_STATIC_WHITE_M, FALSE);
|
||
}
|
||
|
||
void TBuildInfomationDlg::AfterSelectRedline()
|
||
{
|
||
EnableCtrl(this, IDC_EDIT_UP_AOTO, TRUE);
|
||
EnableCtrl(this, IDC_EDIT_UP_BIKE, TRUE);
|
||
EnableCtrl(this, IDC_EDIT_GREEN_RATIO, TRUE);
|
||
EnableCtrl(this, IDC_EDIT_BUILD_DENSITY, TRUE);
|
||
EnableCtrl(this, IDC_EDIT_UP_BUILD_AREA, TRUE);
|
||
EnableCtrl(this, IDC_EDIT_DOWN_BUILD_AREA, TRUE);
|
||
EnableCtrl(this, IDC_BUTTON_CALC, TRUE);
|
||
|
||
ShowBackLineCtrl();
|
||
}
|
||
|
||
void TBuildInfomationDlg::RemoveColorLine()
|
||
{
|
||
TDocLock lock;
|
||
for (size_t i = 0; i < m_redline.m_colorLines.size(); ++i)
|
||
{
|
||
OPENOBJ_BEGIN(m_redline.m_colorLines[i], AcDb::kForWrite, AcDbEntity, pl)
|
||
{
|
||
if (!pl) continue;
|
||
Acad::ErrorStatus es = pl->erase();
|
||
}
|
||
OPENOBJ_END()
|
||
}
|
||
}
|
||
|
||
HBRUSH TBuildInfomationDlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)
|
||
{
|
||
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
|
||
HWND hwnd = pWnd->GetSafeHwnd();
|
||
if (nCtlColor == CTLCOLOR_STATIC || nCtlColor == CTLCOLOR_EDIT)
|
||
{
|
||
if (hwnd == GetDlgItem(IDC_STATIC_RED)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_STATIC_RED_M)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_EDIT_RED)->GetSafeHwnd() )
|
||
{
|
||
pDC->SetTextColor(RGB(255, 0, 0));
|
||
}
|
||
else if (hwnd == GetDlgItem(IDC_STATIC_YELLOW)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_STATIC_YELLOW_M)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_EDIT_YELLOW)->GetSafeHwnd() )
|
||
{
|
||
pDC->SetTextColor(RGB(255, 255, 0));
|
||
}
|
||
else if (hwnd == GetDlgItem(IDC_STATIC_GREEN)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_STATIC_GREEN_M)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_EDIT_GREEN)->GetSafeHwnd() )
|
||
{
|
||
pDC->SetTextColor(RGB(0, 255, 0));
|
||
}
|
||
else if (hwnd == GetDlgItem(IDC_STATIC_CYAN)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_STATIC_CYAN_M)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_EDIT_CYAN)->GetSafeHwnd() )
|
||
{
|
||
pDC->SetTextColor(RGB(0, 255, 255));
|
||
}
|
||
else if (hwnd == GetDlgItem(IDC_STATIC_BLUE)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_STATIC_BLUE_M)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_EDIT_BLUE)->GetSafeHwnd() )
|
||
{
|
||
pDC->SetTextColor(RGB(0, 0, 255));
|
||
}
|
||
else if (hwnd == GetDlgItem(IDC_STATIC_MAGENTA)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_STATIC_MAGENTA_M)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_EDIT_MAGENTA)->GetSafeHwnd() )
|
||
{
|
||
pDC->SetTextColor(RGB(255, 0, 255));
|
||
}
|
||
else if (hwnd == GetDlgItem(IDC_STATIC_WHITE)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_STATIC_WHITE_M)->GetSafeHwnd() ||
|
||
hwnd == GetDlgItem(IDC_EDIT_WHITE)->GetSafeHwnd() )
|
||
{
|
||
pDC->SetTextColor(RGB(255, 255, 255));
|
||
}
|
||
}
|
||
return hbr;
|
||
}
|
||
|
||
void TBuildInfomationDlg::OnEnKillfocusEdit()
|
||
{
|
||
UpdateData(TRUE);
|
||
}
|
||
|
||
LONG_PTR TBuildInfomationDlg::OnAcadKeepFocus(UINT_PTR, LONG_PTR)
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
void TRedLine::CalcBackLine()
|
||
{
|
||
// 先得出相应位移后的线段
|
||
std::vector<AcGeLineSeg3d> segs;
|
||
AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin), ptTmp(AcGePoint3d::kOrigin);
|
||
AcGeLineSeg3d seg, segnew;
|
||
AcGeVector3d vt(AcGeVector3d::kIdentity);
|
||
AcGeRay3d ray;
|
||
for (size_t i = 0; i < m_RedSegs.size(); ++i)
|
||
{
|
||
segnew = seg = m_RedSegs[i];
|
||
ptS = seg.startPoint(), ptE = seg.endPoint();
|
||
vt = ptE - ptS;
|
||
vt.normalize();
|
||
vt.rotateBy(PI*.5, AcGeVector3d::kZAxis);
|
||
vt *= 5; // 稍放长一些,用些来判断是否指向poly内部
|
||
|
||
// 判断
|
||
ptTmp = seg.midPoint();
|
||
ptTmp += vt;
|
||
if ((ptTmp & m_RedlinePoly) != PR_INSIDE)
|
||
vt.rotateBy(PI, AcGeVector3d::kZAxis);
|
||
|
||
vt.normalize();
|
||
vt *= GetBacklineValue((int)i);
|
||
|
||
segnew.transformBy(vt);
|
||
segs.push_back(segnew);
|
||
}
|
||
|
||
AcGeLineSeg3d seg1, seg2;
|
||
|
||
// 为保证退线线段顺序与红线一至,先把第一段与最后一段求交点。做为退线的第一个点
|
||
seg1 = segs[0], seg2 = segs[segs.size() - 1];
|
||
seg1.intersectWith(seg2, ptTmp);
|
||
m_BacklinePoly.AppendNode(ptTmp);
|
||
for (size_t i = 0; i < segs.size(); ++i)
|
||
{
|
||
seg1 = segs[i];
|
||
if (i + 1 < segs.size())
|
||
seg2 = segs[i + 1];
|
||
else
|
||
break;
|
||
seg1.intersectWith(seg2, ptTmp);
|
||
m_BacklinePoly.AppendNode(ptTmp);
|
||
}
|
||
m_BacklinePoly.SetClosed();
|
||
|
||
m_dBackLineArea = m_BacklinePoly.Area();
|
||
// if (!DocGetMeterUnitDraw())
|
||
// m_dBackLineArea /= 1000000;
|
||
|
||
TDocLock lock;
|
||
Insert2MSpace(m_BacklinePoly, _T("总图-建筑退线"));
|
||
}
|
||
|
||
double TRedLine::GetBacklineValue(const int &idx)
|
||
{
|
||
if (idx > 7) return .0;
|
||
int num = idx + 1;
|
||
double dRel(.0);
|
||
if (num == 1) dRel = m_dBacklineRed;
|
||
else if (num == 2) dRel = m_dBacklineYellow;
|
||
else if (num == 3) dRel = m_dBacklineGreen;
|
||
else if (num == 4) dRel = m_dBacklineCyan;
|
||
else if (num == 5) dRel = m_dBacklineBlue;
|
||
else if (num == 6) dRel = m_dBacklineMagenta;
|
||
else if (num == 7) dRel = m_dBacklineWhite;
|
||
// if (!DocGetMeterUnitDraw())
|
||
// dRel *= 1000;
|
||
return dRel;
|
||
}
|
||
|
||
double TRedLine::CalcNo3Step()
|
||
{
|
||
double S = m_dRedlineArea;
|
||
double A1 = m_dBackLineArea; // 退线面积
|
||
int a = m_nUpAtuoNum; // 机动车数量
|
||
double SI = a * 25.; // 机动车停车面积
|
||
int b = m_nUpBikeNum; // 非机动车数量
|
||
double SII = b* 1.75; // 非机动车停车面积
|
||
double c = m_dGreen; // 绿化率
|
||
double SIII = S * c*.01;
|
||
double A2 = S - SI - SII - SIII;
|
||
double e = m_dBuildDensity; // 建筑密度
|
||
double A3 = S * e;
|
||
m_dUpBuildArea *= 10000;
|
||
m_dDownBuildArea *= 10000;
|
||
m_dVolume = m_dUpBuildArea / m_dRedlineArea;
|
||
|
||
std::vector<double> areas(0);
|
||
areas.push_back(A1);
|
||
areas.push_back(A2);
|
||
areas.push_back(A3);
|
||
std::sort(areas.begin(), areas.end()); // 排序求出最小值
|
||
|
||
return *areas.begin();
|
||
}
|
||
|
||
bool TRedLine::CalcNo4Step()
|
||
{
|
||
CString str(_T(""));
|
||
double a, b, h1, h2; // 未知
|
||
double S1(7000.), S2(21000.), h1Max(75.), h1Min(45.), h2Max(155.), h2Min(90.), abMax(60.), abMin(55.),
|
||
d1(8.4), // 建筑线与退线之间的距离
|
||
d2(4.), // 建筑线与屋顶采光的距离
|
||
dw(4.3); // 屋顶采光半宽
|
||
|
||
// 先进行验证
|
||
AcGeLineSeg3d segDirect = GetBLDirectSeg();
|
||
AcGeLineSeg3d segCloses = GetBLClosesSeg();
|
||
|
||
// 当2*a,,h2都为最小时,其和应该小于退线的方向线段
|
||
double dd = segDirect.length();
|
||
if (segDirect.length() < (h2Min + abMin + abMin))
|
||
{
|
||
str.Format(_T("退线边的长度%.2f小于 h2的最小值%.2f与 2*a的小最值%.2f的和."), segDirect.length(), h2Min, 2*abMin);
|
||
AfxMessageBox(str);
|
||
return false;
|
||
}
|
||
|
||
// 当b,h2都为最小时,其和应该小于退线的垂直于方向线段的高度
|
||
//if (segCloses.length() < (h1Min + abMin)) return false;
|
||
|
||
// 先求h2长度,假设 a = 60 , A为退线方向边的长度,令 A = h2 + 2*a,则h2 = A - 2*a
|
||
a = abMax;
|
||
double A = segDirect.length();
|
||
h2 = A - 2 * a;
|
||
if (h2 > h2Max)
|
||
{
|
||
h2 = h2Max;
|
||
// 此时 a = abMax, h2 = h2Max, 与 A 之间一定满足关系,不需再次验证
|
||
// 通过验证,则 a 已知,S1已知,求h2
|
||
}
|
||
else if (h2 < h2Min)
|
||
{
|
||
h2 = h2Min;
|
||
// 此时,由于放大了h2的值,所以 2*a+h2 的值有可能大于A,所以需要再次验证
|
||
if (A < h2 + 2*a)
|
||
{
|
||
// 如果a取最小通过验证,则做几个循环,找到精确值(精为1m)。a应该越大越好。所以a从59开始验证
|
||
for (a = 60; a <= 55; a-=.001)
|
||
if (A >= h2 + 2 * a) break;
|
||
}
|
||
}
|
||
|
||
bool brel(false);
|
||
double delta = .1;
|
||
CalcLightBuildPoly(a, h2, S1, h1);
|
||
while (true)
|
||
{
|
||
if (h1 <= h1Max && h1 >= h1Min)
|
||
{
|
||
brel = true;
|
||
break;
|
||
}
|
||
if (h1 < h1Min)
|
||
{
|
||
h2 -= delta;
|
||
if (h2 <= h2Min)
|
||
{
|
||
str.Format(_T("\nh2为最小值%.2f时,h1=%.2f依然不满足 %.2f < h1 < %.2f。\n,是否继续绘制不标准的曲线?"), h2Min, h1, h1Min, h1Max);
|
||
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
|
||
brel = true;
|
||
break;
|
||
}
|
||
CalcLightBuildPoly(a, h2, S1, h1);
|
||
}
|
||
else if (h1 > h2Max)
|
||
{
|
||
h2 += delta;
|
||
if (h2 >= h2Max)
|
||
{
|
||
str.Format(_T("\nh2为最大值%.2f时,h1=%.2f依然不满足 %.2f < h1 < %.2f。\n,是否继续绘制不标准的曲线?"), h2Max, h1, h1Min, h1Max);
|
||
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
|
||
brel = true;
|
||
break;
|
||
}
|
||
CalcLightBuildPoly(a, h2, S1, h1);
|
||
}
|
||
}
|
||
|
||
if (brel)
|
||
{
|
||
g_idLight = Insert2MSpace(m_LightBuildPoly, _T("轻资产"));
|
||
}
|
||
|
||
CalcBuildPoly(a, h1, h2, S1, S2, b);
|
||
while (true)
|
||
{
|
||
if (b <= abMax && b >= abMin)
|
||
{
|
||
brel = true;
|
||
break;
|
||
}
|
||
if (b < abMin)
|
||
{
|
||
a -= delta;
|
||
if (a <= abMin)
|
||
{
|
||
str.Format(_T("\na为最小值%.2f时,b=%.2f依然不满足 %.2f < b < %.2f。\n,是否继续绘制不标准的曲线?"), abMin, b, abMin, abMax);
|
||
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
|
||
brel = true;
|
||
break;
|
||
}
|
||
CalcBuildPoly(a, h1, h2, S1, S2, b);
|
||
}
|
||
else if (b > abMax)
|
||
{
|
||
a += delta;
|
||
if (a >= abMax)
|
||
{
|
||
str.Format(_T("\na为最大值%.2f时,b=%.2f依然不满足 %.2f < b < %.2f。\n,是否继续绘制不标准的曲线?"), abMax, b, abMin, abMax);
|
||
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
|
||
brel = true;
|
||
break;
|
||
}
|
||
CalcBuildPoly(a, h1, h2, S1, S2, b);
|
||
}
|
||
}
|
||
|
||
if (brel)
|
||
{
|
||
g_idBuild = Insert2MSpace(m_BuildPoly, _T("总图-建筑轮廓线"));
|
||
}
|
||
|
||
if (brel)
|
||
CalcCurtainPoly(b, h1);
|
||
|
||
return brel;
|
||
}
|
||
|
||
AcGeLineSeg3d TRedLine::GetSegByIdx(const int &idx, const TGGePoly3D &poly)
|
||
{
|
||
if (idx >= 0 && idx < poly.TotalSegments())
|
||
{
|
||
TGGeCurveSegment seg;
|
||
poly.Nth(idx, seg);
|
||
return AcGeLineSeg3d(seg.StartPoint().AsAcGePoint3d(), seg.EndPoint().AsAcGePoint3d());
|
||
}
|
||
return AcGeLineSeg3d(AcGePoint3d::kOrigin, AcGePoint3d::kOrigin);
|
||
}
|
||
|
||
AcGeLineSeg3d TRedLine::GetBLDirectSeg() { return GetSegByIdx(m_idxDirect, m_BacklinePoly); }
|
||
|
||
AcGeLineSeg3d TRedLine::GetBLClosesSeg() { return GetSegByIdx(m_idxCloses, m_BacklinePoly); }
|
||
|
||
AcGeLineSeg3d TRedLine::GetBLOtherSeg() { return GetSegByIdx(m_idxOther, m_BacklinePoly); }
|
||
|
||
/************************************************************************/
|
||
// 此多段线各边与退线各边平行。
|
||
// 其中一边与退线方向边重合。长度为 a
|
||
// 围成面积为S1=7000
|
||
// 在这个算法里,由于a值是固定的,所以底边的长度和方向,和与其相邻两边的方向是固定不动的。
|
||
// 取底边的一条邻边(e),令e的另一条邻边(e1)(非底边),向底边方向移动。(e与e1的交点沿e向底边移动。)来得到面积为S1的多段线。
|
||
|
||
/*
|
||
轻建筑左边e2 轻建筑右边e1
|
||
方向边的另一边 | | 退线最近边
|
||
| | | |
|
||
| | | |
|
||
| ------------------ 轻建筑底边e | (轻建筑度边与退线方向边重合)
|
||
| ptE2 ptE1 | ptE2与ptE1距离为h2
|
||
|___________________________________________________| 退线方向边
|
||
ptOther ptCloses ptE1与ptCloses的距离为a
|
||
*/
|
||
|
||
/************************************************************************/
|
||
bool TRedLine::CalcLightBuildPoly(const double &a, const double &h2, const double &S1, double &h1)
|
||
{
|
||
AcGePoint3d ptE1(AcGePoint3d::kOrigin); // 轻建筑底边与与右边e1的交点
|
||
AcGePoint3d ptE2(AcGePoint3d::kOrigin); // 轻建筑底边与与左边e2的交点
|
||
AcGeLineSeg3d segBottom; // 轻建筑曲线的底边。
|
||
AcGeLineSeg3d segLeft; // 轻建筑左边
|
||
AcGeLineSeg3d segRight; // 轻建筑右边
|
||
AcGeLineSeg3d segOther; // 退线方向边的另一边(非最近边)
|
||
|
||
|
||
// 首先取出退线的方向边儿, 与最近边。并得取方向边与最近边的交点
|
||
AcGeLineSeg3d segBLDirect = GetBLDirectSeg();
|
||
AcGeLineSeg3d segBLCloses = GetBLClosesSeg();
|
||
AcGeLineSeg3d segBLOther = GetBLOtherSeg();
|
||
|
||
// 得到轻建筑左右点坐标(此两点都在退线方向边儿上)
|
||
m_vtDirect.normalize();
|
||
m_vtDirect *= a;
|
||
ptE1 = m_ptCloses + m_vtDirect;
|
||
m_vtDirect.normalize();
|
||
m_vtDirect *= h2;
|
||
ptE2 = ptE1 + m_vtDirect;
|
||
|
||
// 取与退线方向边重合等长的边,沿着vtE1方向移动,移动时保持与退线方向线段平行。
|
||
AcGeLineSeg3d seg = segBLDirect;
|
||
m_vtCloses.normalize();
|
||
double delta = .0001; // 1/10毫米单位拟合
|
||
m_LightBuildPoly.SetClosed();
|
||
AcGeRay3d ray1(ptE1, m_vtCloses), ray2(ptE2, m_vtOther);
|
||
|
||
m_segLightDirect.set(ptE1, ptE2);
|
||
m_DimH1 = std::make_pair(ptE1, ptE2);
|
||
|
||
AcGeVector3d _vt(ptE1 - ptE2);
|
||
_vt.normalize();
|
||
_vt *= a;
|
||
m_DimA1 = std::make_pair(ptE1, ptE1+_vt);
|
||
m_DimA2 = std::make_pair(ptE2, ptE2-_vt);
|
||
|
||
AcGePoint3d pt, ptE;
|
||
while (true)
|
||
{
|
||
m_LightBuildPoly.Reset();
|
||
m_LightBuildPoly.AppendNode(ptE1);
|
||
m_LightBuildPoly.AppendNode(ptE2);
|
||
m_vtCloses.normalize();
|
||
m_vtCloses *= delta;
|
||
delta += .0001;
|
||
|
||
seg.transformBy(m_vtCloses);
|
||
|
||
seg.intersectWith(ray2, pt);
|
||
m_LightBuildPoly.AppendNode(pt);
|
||
m_segLightOther.set(ptE2, pt);
|
||
seg.intersectWith(ray1, pt);
|
||
m_LightBuildPoly.AppendNode(pt);
|
||
m_segLightCloses.set(ptE1, pt);
|
||
|
||
m_LightBuildPoly.SetClosed();
|
||
double dArea = m_LightBuildPoly.Area();
|
||
if (dArea > S1 )
|
||
{
|
||
ptE = segBLDirect.closestPointTo(pt);
|
||
h1 = ptE.distanceTo(pt);
|
||
m_DimH2 = std::make_pair(ptE, pt);
|
||
break;
|
||
}
|
||
}
|
||
|
||
{ // 计算轻资产标注插入点
|
||
AcGeVector3d vt = -m_vtDirect;
|
||
m_ptInsertLightDim1 = m_segLightOther.endPoint();
|
||
vt.normalize();
|
||
vt *= 15;
|
||
m_ptInsertLightDim1 += vt;
|
||
vt = -m_vtOther;
|
||
vt.normalize();
|
||
vt *= 15;
|
||
m_ptInsertLightDim1 += vt;
|
||
vt.normalize();
|
||
vt *= 15;
|
||
m_ptInsertLightDim2 = m_ptInsertLightDim1;
|
||
m_ptInsertLightDim2 += vt;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// 计算出围绕S1(light build)的处围曲线
|
||
/************************************************************************/
|
||
/*
|
||
建筑线另一边 轻建筑左边e2 轻建筑右边e1
|
||
方向边的另一边 | | | 退线最近边(建筑线也在此,与退线最近边重合)
|
||
| | | | | |
|
||
| | | | | |
|
||
| | ------------------ 轻建筑底边e | | (轻建筑度边与退线方向边重合)
|
||
| | ptE2 ptE1 | | ptE2与ptE1距离为h2
|
||
| |_______________________________________________________| |
|
||
| ptB2 ptB1|
|
||
|______________________________________________________________________| 退线方向边
|
||
ptOther ptCloses ptE1与ptCloses的距离为a
|
||
*/
|
||
|
||
/************************************************************************/
|
||
bool TRedLine::CalcBuildPoly(const double &a, const double &h1, const double &h2, const double &S1, const double &S2, double &b)
|
||
{
|
||
double d1(8.4), // 建筑线与退线之间的距离
|
||
d2(4.), // 建筑线与屋顶采光的距离
|
||
dw(4.3); // 屋顶采光半宽
|
||
|
||
AcGeLineSeg3d segBLDirect = GetBLDirectSeg();
|
||
AcGeLineSeg3d segBLCloses = GetBLClosesSeg();
|
||
AcGeLineSeg3d segBLOther = GetBLOtherSeg();
|
||
|
||
AcGeVector3d vt(AcGeVector3d::kIdentity);
|
||
AcGePoint3d pt(AcGePoint3d::kOrigin);
|
||
AcGeLineSeg3d seg;
|
||
|
||
AcGePoint3d ptB1(AcGePoint3d::kOrigin), ptB2(AcGePoint3d::kOrigin),
|
||
ptB11(AcGePoint3d::kOrigin), ptB22(AcGePoint3d::kOrigin),
|
||
ptB111(AcGePoint3d::kOrigin), ptB222(AcGePoint3d::kOrigin);
|
||
// 得取ptB1与ptB2点
|
||
ptB1 = m_ptCloses;
|
||
m_vtDirect.normalize();
|
||
m_vtDirect*= (h2 + 2 * a);
|
||
ptB2 = ptB1 + m_vtDirect;
|
||
|
||
AcGeRay3d ray1(ptB1, m_vtCloses);
|
||
AcGeRay3d ray2(ptB2, m_vtOther);
|
||
|
||
vt = m_vtDirect;
|
||
vt.normalize();
|
||
vt *=5;
|
||
vt.rotateBy(PI*.5, AcGeVector3d::kZAxis);
|
||
pt = segBLDirect.midPoint();
|
||
pt = pt + vt;
|
||
if ((pt & m_BacklinePoly) != PR_INSIDE)
|
||
vt.rotateBy(PI, AcGeVector3d::kZAxis);
|
||
vt.normalize();
|
||
vt *= d1;
|
||
|
||
seg = segBLDirect;
|
||
seg.transformBy(vt);
|
||
|
||
ray1.intersectWith(seg, ptB1);
|
||
ray2.intersectWith(seg, ptB2);
|
||
|
||
seg.intersectWith(m_segLightOther, ptB22);
|
||
seg.intersectWith(m_segLightCloses, ptB11);
|
||
|
||
ptB111 = m_segLightCloses.endPoint();
|
||
ptB222 = m_segLightOther.endPoint();
|
||
|
||
// 进行拟合,沿m_vtCloses方向移动seg线段
|
||
double delta = .0001;
|
||
m_vtCloses.normalize();
|
||
m_vtCloses *= (m_segLightCloses.length()+delta);
|
||
seg = segBLDirect;
|
||
seg.transformBy(m_vtCloses);
|
||
|
||
while (true)
|
||
{
|
||
m_BuildPoly.Reset();
|
||
m_BuildPoly.AppendNode(ptB1);
|
||
seg.intersectWith(ray1, pt);
|
||
m_BuildPoly.AppendNode(pt);
|
||
seg.intersectWith(ray2, pt);
|
||
m_BuildPoly.AppendNode(pt);
|
||
m_segBuildCloses.set(ptB2, pt);
|
||
seg.intersectWith(ray2, pt);
|
||
m_BuildPoly.AppendNode(ptB2);
|
||
m_BuildPoly.AppendNode(ptB22);
|
||
m_BuildPoly.AppendNode(m_segLightOther.endPoint());
|
||
m_BuildPoly.AppendNode(m_segLightCloses.endPoint());
|
||
m_BuildPoly.AppendNode(ptB11);
|
||
m_BuildPoly.SetClosed();
|
||
|
||
m_segBuildCloses1.set(ptB1, ptB11);
|
||
m_segBuildOther1.set(ptB2, ptB22);
|
||
|
||
m_vtCloses.normalize();
|
||
m_vtCloses *= delta;
|
||
delta += .0001;
|
||
seg.transformBy(m_vtCloses);
|
||
if (m_BuildPoly.Area() > S2)
|
||
{
|
||
pt = seg.closestPointTo(m_segLightCloses.endPoint());
|
||
b = pt.distanceTo(m_segLightCloses.endPoint());
|
||
m_DimB = std::make_pair(pt, m_segLightCloses.endPoint());
|
||
break;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void TRedLine::CalcCurtainPoly(const double &b, const double &h1)
|
||
{
|
||
AcGePoint3d pt(AcGePoint3d::kOrigin);
|
||
AcGeVector3d vt(AcGeVector3d::kIdentity);
|
||
AcGeLineSeg3d seg, seg1, seg2, seg3;
|
||
// 建筑线求得幕墙中线
|
||
AcGePoint3d ptMidB1 = m_segBuildCloses1.midPoint();
|
||
AcGePoint3d ptMidB2 = m_segBuildOther1.midPoint();
|
||
|
||
AcGePoint3d ptMid1(ptMidB1), ptMid2(ptMidB2); // 计算步行街长度
|
||
|
||
vt = m_vtDirect;
|
||
vt.normalize();
|
||
vt *= 5;
|
||
vt.rotateBy(PI*.5, AcGeVector3d::kZAxis);
|
||
pt = m_segLightDirect.midPoint();
|
||
pt += vt;
|
||
if ((pt & m_LightBuildPoly) != PR_INSIDE)
|
||
vt.rotateBy(PI, AcGeVector3d::kZAxis);
|
||
vt.normalize();
|
||
vt *= 4;
|
||
ptMidB1 += vt;
|
||
ptMidB2 += vt;
|
||
|
||
vt.normalize();
|
||
vt *= (h1 + b*.5);
|
||
seg = GetBLDirectSeg();
|
||
seg.transformBy(vt);
|
||
AcGeLineSeg3d segMid = seg;
|
||
|
||
{ // 计算步行街长度和插入标注的位置
|
||
AcGePoint3d pt1, pt2;
|
||
AcGeRay3d ray1(ptMid1, m_vtCloses);
|
||
ray1.intersectWith(segMid, pt1);
|
||
AcGeRay3d ray2(ptMid2, m_vtOther);
|
||
ray2.intersectWith(segMid, pt2);
|
||
m_dFootLength += ptMid1.distanceTo(pt1);
|
||
m_dFootLength += ptMid2.distanceTo(pt2);
|
||
m_dFootLength += pt2.distanceTo(pt1);
|
||
AcGeLineSeg3d seg(segMid);
|
||
AcGeVector3d vt(m_vtOther);
|
||
vt.normalize();
|
||
vt *= 15;
|
||
seg.transformBy(vt);
|
||
ray2.intersectWith(seg, m_ptInsertFootDim);
|
||
}
|
||
|
||
double dw = 4.3; //采光半宽
|
||
double dta = 11; // 椭圆a轴
|
||
double dtb = 16; // 椭圆b轴
|
||
double dtd = 4; // 椭圆与采光的间距
|
||
|
||
TGGePoly3D poly1, poly2;
|
||
|
||
AcGePoint3d ptMidLightDirect = m_segLightDirect.midPoint();
|
||
|
||
vt = m_vtDirect;
|
||
vt.normalize();
|
||
vt.rotateBy(3*PI*.5, AcGeVector3d::kZAxis);
|
||
vt *= dw;
|
||
AcGeLineSeg3d segUp = seg;
|
||
segUp.transformBy(vt);
|
||
AcGeLineSeg3d segDown = seg;
|
||
segDown.transformBy(-vt);
|
||
|
||
pt = segUp.closestPointTo(ptMidLightDirect);
|
||
double dUp = pt.distanceTo(ptMidLightDirect);
|
||
pt = segDown.closestPointTo(ptMidLightDirect);
|
||
double dDown = pt.distanceTo(ptMidLightDirect);
|
||
|
||
if (dDown > dUp)
|
||
{
|
||
seg = segUp;
|
||
segUp = segDown;
|
||
segDown = seg;
|
||
}
|
||
|
||
AcGePoint3d pt1, pt2, pt3, pt4, pt5, pt6;
|
||
|
||
vt = m_vtDirect;
|
||
vt.normalize();
|
||
vt *= dw;
|
||
pt1 = ptMidB1 - vt;
|
||
pt6 = ptMidB1 + vt;
|
||
|
||
pt = m_segLightCloses.closestPointTo(pt1);
|
||
double d1 = pt.distanceTo(pt1);
|
||
pt = m_segLightCloses.closestPointTo(pt6);
|
||
double d6 = pt.distanceTo(pt6);
|
||
if (d1 < d6)
|
||
{
|
||
pt = pt1;
|
||
pt1 = pt6;
|
||
pt6 = pt;
|
||
}
|
||
|
||
AcGeRay3d ray1(pt1, m_vtCloses);
|
||
ray1.intersectWith(segUp, pt2);
|
||
|
||
vt = -m_vtDirect;
|
||
vt.normalize();
|
||
vt *= (dtb + dtd);
|
||
pt3 = segUp.closestPointTo(m_segLightDirect.midPoint());
|
||
pt3 += vt;
|
||
|
||
pt4 = segDown.closestPointTo(m_segLightDirect.midPoint());
|
||
pt4 += vt;
|
||
|
||
AcGeRay3d ray2(pt6, m_vtCloses);
|
||
ray2.intersectWith(segDown, pt5);
|
||
poly1.AppendNode(pt1);
|
||
poly1.AppendNode(pt2);
|
||
poly1.AppendNode(pt3);
|
||
poly1.AppendNode(pt4);
|
||
poly1.AppendNode(pt5);
|
||
poly1.AppendNode(pt6);
|
||
poly1.SetClosed();
|
||
|
||
|
||
vt = m_vtDirect;
|
||
vt.normalize();
|
||
vt *= dw;
|
||
pt1 = ptMidB2 + vt;
|
||
pt6 = ptMidB2 - vt;
|
||
|
||
pt = m_segLightOther.closestPointTo(pt1);
|
||
d1 = pt.distanceTo(pt1);
|
||
pt = m_segLightOther.closestPointTo(pt6);
|
||
d6 = pt.distanceTo(pt6);
|
||
if (d1 < d6)
|
||
{
|
||
pt = pt1;
|
||
pt1 = pt6;
|
||
pt6 = pt;
|
||
}
|
||
|
||
AcGeRay3d ray3(pt1, m_vtOther);
|
||
ray3.intersectWith(segUp, pt2);
|
||
|
||
vt = m_vtDirect;
|
||
vt.normalize();
|
||
vt *= (dtb + dtd);
|
||
pt3 = segUp.closestPointTo(m_segLightDirect.midPoint());
|
||
pt3 += vt;
|
||
|
||
pt4 = segDown.closestPointTo(m_segLightDirect.midPoint());
|
||
pt4 += vt;
|
||
|
||
AcGeRay3d ray4(pt6, m_vtOther);
|
||
ray4.intersectWith(segDown, pt5);
|
||
poly2.AppendNode(pt1);
|
||
poly2.AppendNode(pt2);
|
||
poly2.AppendNode(pt3);
|
||
poly2.AppendNode(pt4);
|
||
poly2.AppendNode(pt5);
|
||
poly2.AppendNode(pt6);
|
||
poly2.SetClosed();
|
||
|
||
AcDbObjectId id1 = Insert2MSpace(poly1, _T("总图-采光顶"));
|
||
AcDbObjectId id2 = Insert2MSpace(poly2, _T("总图-采光顶"));
|
||
|
||
pt = segMid.closestPointTo(m_segLightDirect.midPoint());
|
||
vt = m_vtDirect;
|
||
vt.normalize();
|
||
vt *= 16;
|
||
AcDbEllipse *pE = new AcDbEllipse(pt, AcGeVector3d::kZAxis, vt, 11./16.);
|
||
pE->setLayer(_T("总图-采光顶"));
|
||
AcDbObjectId id3 = AddToModelSpace(pE);
|
||
AcDbObjectIdArray ar;
|
||
ar.append(id1);
|
||
CreateHatchForObj(ar);
|
||
ar.append(id1);
|
||
ar.removeAll();
|
||
ar.append(id2);
|
||
CreateHatchForObj(ar);
|
||
ar.removeAll();
|
||
ar.append(id3);
|
||
CreateHatchForObj(ar);
|
||
}
|
||
|
||
void TRedLine::CalcDim()
|
||
{
|
||
TGGeCurveSegment seg;
|
||
TGGeLine line;
|
||
AcGePoint3d pt, ptMid;
|
||
for (size_t i = 0; i < m_RedSegs.size(); ++i)
|
||
{
|
||
m_BacklinePoly.Nth(i, seg);
|
||
line.SetStartPoint(seg.StartPoint());
|
||
line.SetEndPoint(seg.EndPoint());
|
||
pt = m_RedSegs[i].closestPointTo(line.MidPoint().AsAcGePoint3d());
|
||
Dim2Pt(pt, line.MidPoint().AsAcGePoint3d());
|
||
}
|
||
|
||
Dim2Pt(m_DimA1.first, m_DimA1.second);
|
||
Dim2Pt(m_DimA2.first, m_DimA2.second);
|
||
Dim2Pt(m_DimB.first, m_DimB.second);
|
||
Dim2Pt(m_DimH1.first, m_DimH1.second);
|
||
Dim2Pt(m_DimH2.first, m_DimH2.second);
|
||
}
|