老师,您好
请问一下,我看我想实现如下视频所示的,放置cell时,cell的方向和鼠标的方向一致,该如何设置旋转矩阵?谢谢。
视频无法播放,您现在能获取到的都有哪些信息?
郭老师好,就是我要绘制道路箭头,确定cell的第一个原点后,箭头的方向随着鼠标动态的移动,鼠标点击第二个点后就确定了箭头的位置。
郭老师,这个出来的结果是乱的,如下图。
HongQiang Guo said:另外最好先不要用共享单元来做,最好是先用普通单元实现想要的效果了,再一点一点改造成共享单元。
这个用普通单元只是把mdlSharedCell_create换成mdlCell_placeCell 函数,区别不是很大?谢谢。
首先您这个导向标志单元是不是一定放到水平面上了?如果不是的话,则Z轴就不能是世界坐标系的Z轴了,而是再计算完Y轴之后要再用direction跟Y轴叉乘算出来Z轴。其次您还要保证您这个导向单元制作时其箭头指向的方向要是X轴。
HongQiang Guo said:首先您这个导向标志单元是不是一定放到水平面上了?如果不是的话,则Z轴就不能是世界坐标系的Z轴了,而是再计算完Y轴之后要再用direction跟Y轴叉乘算出来Z轴。
郭老师,我的导向标志单元不是一定要放在平面上,鼠标的两点就是我的X轴的方向,Y轴不知道该怎么计算?望您指教。
HongQiang Guo said:其次您还要保证您这个导向单元制作时其箭头指向的方向要是X轴
这个X轴指的的是指向世界坐标系的X轴就可以了?
nian chen said:Y轴不知道该怎么计算?
Y轴还是原来的计算方法呀
nian chen said:X轴指的的是指向世界坐标系的X轴
这个不是程序里边,这个时您制作单元库的时候要设定好的
两点只能算出一个X轴的方向吧,Y轴和Z轴都是不确定的吧?
两点构成X轴方向,然后这个X轴方向再跟世界坐标系的Z轴叉乘得到Y轴方向,再用计算出来的X轴和Y轴叉乘不久得到Z轴方向了嘛
郭老师,我还是实现不了,下面是我的半成品代码,您可以帮忙做个demo?感激不尽。
MSElement CreateRoadMark(DPoint3dR basePt, DPoint3dR nextPoint) { MSElement msElement; DPoint3d scale = { 1,1,1 }; DPoint3d origin = { basePt.x, basePt.y, basePt.z }; DVec3d direction = DVec3d::FromStartEnd(basePt, nextPoint); DVec3d z_axis = DVec3d::UnitZ(); DVec3d y_axis = DVec3d::FromCrossProduct(direction, z_axis); DVec3d zz_axis = DVec3d::FromCrossProduct(direction, y_axis); zz_axis.Normalize(); y_axis.Normalize(); double scale_length = basePt.Distance(nextPoint) / 10000 / 3; RotMatrix rMatrix = RotMatrix::FromColumnVectors(scale_length*y_axis, direction, scale_length*zz_axis); mdlSharedCell_create(&msElement, NULL, &origin, &rMatrix, &scale, L"直行_右转箭头", NULL, FALSE, 0, NULL); if (SUCCESS != mdlSharedCell_makeSureDefExists(&msElement)) { mdlDialog_openAlert(L"可能没有连接单元库FlatAssets.cell"); return msElement; } mdlSharedCell_setRange(&msElement, ACTIVEMODEL); return msElement; }
如下示例代码所示:
void PlaceRoadCell(DPoint3dR ptOri, DPoint3dR ptTar) { DPoint3d scale = { 1,1,1 }; DVec3d direction = DVec3d::FromStartEnd(ptOri, ptTar); DVec3d z_axis = DVec3d::UnitZ(); DVec3d y_axis = DVec3d::FromCrossProduct(z_axis, direction); DVec3d zz_axis = DVec3d::FromCrossProduct(direction, y_axis); zz_axis.Normalize(); y_axis.Normalize(); direction.Normalize(); double scale_length = ptOri.Distance(ptTar) / ACTIVEMODEL->GetModelInfoCP()->GetUorPerMeter()/20;//20 is roarsign's length in the cell library RotMatrix rMatrix = RotMatrix::FromColumnVectors(scale_length*direction, scale_length*y_axis, scale_length*zz_axis); mdlCell_placeCell(&ptOri, &scale, false, &rMatrix, NULL, 0, false, 0, 0, L"RoadSign", NULL); }
这是相应的单元库文件:
Cell.dgn
Answer Verified By: nian chen
谢谢郭老师,刚试了一下,确实可以,只是制作单元库的时候箭头要朝X轴才可以。顺便问一下,如果我的箭头不是朝向X轴,通过cell中的两个点构成的向量和我的鼠标点击的两个点构成的向量,通过这两个向量怎么算出变换矩阵?
那就先构造旋转矩阵,把单元旋转到箭头朝向X轴的方向。