这种类似于框选的效果用的比较普遍,一般三维平台和GIS平台都提供了支持接口,可是Skyline就是这么傲娇!
思路是这样的:绘制出的矩形框应该是一直与屏幕边框平行的,也就是矩形框的实际旋转角度是等于摄像机的偏移角YAW值的,这样我们只要知道矩形的宽度,用矩形的两个对角点沿摄像机方向或者沿摄像机反方向延长一个宽度的距离就能得到矩形的另外两个点了。这个宽度利用两个对角点的距离和摄像机偏移角度很容易就能算出来,就不赘叙了。
最核心的代码就是正确计算矩形对角线与水平方向的夹角了:
1 //计算矩形对角点的夹角 2 private double GetAngle(IPosition6 Poi) 3 { 4 var includeAngle = _sgworld.CoordServices.GetAimingAngles(_Position, Poi); 5 var angle = includeAngle.Yaw - 90 - _Position.Yaw; 6 return (angle / 180 * 3.14); 7 }
其他主要代码抄录如下:
1 SGWorld _sgworld = Application3D.SGworld; 2 private ITerrainPolygon6 _TerrainRctg; 3 private IPosition6 _Position; 4 public ITerrainPolygon6 TerrainRectangle 5 { 6 get { return _TerrainRctg; } 7 } 8 9 //左键开始绘制长方形 10 public bool OnLButtonDown(int Flags, int X, int Y) 11 { 12 if(_Position ==null) 13 { 14 var wpi = _sgworld.Window.PixelToWorld(X, Y, WorldPointType.WPT_DEFAULT); 15 _Position = wpi.Position; 16 _Position.Yaw = _sgworld.Navigate.GetPosition(AltitudeTypeCode.ATC_TERRAIN_ABSOLUTE).Yaw; 17 } 18 else 19 { 20 //第二次点击结束绘制 21 FinshEdit(); 22 } 23 return false; 24 } 25 26 //鼠标移动 27 public void OnFrame() 28 { 29 //创建或更新长方形 30 if (_Position == null) return; 31 32 var mi = _sgworld.Window.GetMouseInfo(); 33 var position = _sgworld.Window.PixelToWorld(mi.X, mi.Y, WorldPointType.WPT_DEFAULT).Position; 34 var length = _Position.DistanceTo(position); 35 var angle = GetAngle(position); 36 var width = Math.Sin(angle) * length; /*这里矩形的宽就得到了*/ 37 38 var poi1 = _Position.Move(width * -1, _Position.Yaw, 0); /*两个对角点沿摄像机方向延伸一个宽度*/ 39 var poi2 = position.Move(width, _Position.Yaw, 0); 40 41 var array = new double[] {_Position .X,_Position .Y,1, 42 poi1 .X ,poi1 .Y ,1, 43 position .X ,position .Y ,1, 44 poi2 .X ,poi2 .Y ,1}; 45 var cRing = _sgworld.Creator.GeometryCreator.CreateLinearRingGeometry(array); 46 var cPolygonGeometry = _sgworld.Creator.GeometryCreator.CreatePolygonGeometry(cRing, null); 47 48 if (_TerrainRctg == null) 49 { 50 var nLineColor = 0xFF00FF00; 51 var nFillColor = 0xBB00FFFF; 52 var eAltitudeTypeCode = AltitudeTypeCode.ATC_TERRAIN_RELATIVE; 53 _TerrainRctg = _sgworld.Creator.CreatePolygon(cPolygonGeometry, nLineColor, nFillColor, eAltitudeTypeCode, parentID, "选中区域"); 54 } 55 else 56 { 57 _TerrainRctg.Geometry = cPolygonGeometry; 58 } 59 }
时间: 2024-10-14 22:44:23