一、技术原理

CityMaker创建体,原理是由点生成线,由线生成面,由面生成体,在三维中都是根据一个点坐标和一些条件(长宽或半径、颜色样式等)来生成体对象,根据视觉可以把体分为:立方体、球、圆锥、圆柱。
接口:

  • 立方体:CreateBox
  • 球:CreateSphere
  • 圆柱:CreateCylinder
  • 圆锥:CreateCone

方法:
一种是通过传入指定的坐标,第二种是实时绘制,例如长方体,可以点击第一个点 创建出来长方体,然后实时移动鼠标的时候更改 右下角x、y点坐标,单击第二个点,确定底面,然后移动位置 更改高度,单击第三个点创建改变高度参数即可

二、创建体

1. .NET

基础方法

  1. public void CreateBox() {
  2. //初始化一个位置对象position
  3. IPosition position = new Position();
  4. //设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)
  5. position.Init(10, 10, 0, 0, 0, 0, gviAltitudeType.gviAltitudeTerrainRelative);
  6. position.Distance = 500;
  7. //创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)
  8. var rBox = rendercontrol.ObjectManager.CreateBox(position, 100, 50, 50, 0xffcccccc, 0xffcccccc, __rootId);
  9. //设置相机飞到线对象
  10. rendercontrol.Camera.FlyToObject(rBox.Guid,gviActionCode.gviActionFlyTo);
  11. //创建圆柱 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)
  12. var rCylinder = rendercontrol.ObjectManager.CreateCylinder(position, 20, 123, 0xff1295EE, 0xFF808080, 100, __rootId);
  13. rendercontrol.Camera.FlyToObject(rCylinder.Guid, gviActionCode.gviActionFlyTo);
  14. //创建圆锥 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)
  15. var rCone = rendercontrol.ObjectManager.CreateCone(position, 20, -123, 0xff1295EE, 0xFF808080, 100, __rootId);
  16. rendercontrol.Camera.FlyToObject(rCone.Guid, gviActionCode.gviActionFlyTo);
  17. //创建球 参数为(位置position对象,半径、显示球类型(0、1、2、3、4分别表示显示全显示、上半部分、下半部分、上半部分包括底面、下半部分包括顶面)、//线框颜色、填充颜色、网格的密度(用来表示球的密度)、组节点guid)
  18. var rSphere = rendercontrol.ObjectManager.CreateSphere(position, 20, 3, 0xffcccccc, 0xFF808080, 10, __rootId);
  19. rendercontrol.Camera.FlyToObject(rSphere.Guid, gviActionCode.gviActionFlyTo);
  20. }

实时绘制立方体

  1. public void Create()
  2. {
  3. // 注册控件拾取事件
  4. this.rendercontrol.RcMouseClickSelect += new Gvitech.CityMaker.Controls._IRenderControlEvents_RcMouseClickSelectEventHandler(RcMouseClickSelect);
  5. this.rendercontrol.InteractMode = gviInteractMode.gviInteractSelect;
  6. this.rendercontrol.MouseSelectObjectMask = gviMouseSelectObjectMask.gviSelectAll;
  7. this.rendercontrol.MouseSelectMode = gviMouseSelectMode.gviMouseSelectClick | gviMouseSelectMode.gviMouseSelectMove;
  8. }
  9. double clickNum = 0;//点击的次数
  10. ITerrain3DRectBase rBox;//立方体对象
  11. double ScreenX1 = 0.0;//第一个点的屏幕坐标
  12. double ScreenY1 = 0.0;
  13. double ScreenX2 = 0.0;//第二个点的屏幕坐标
  14. double ScreenY2 = 0.0;
  15. IPoint point1;//实际第一个点
  16. IPoint point2;//实际第二个点
  17. bool b = false;
  18. //点击事件
  19. public void RcMouseClickSelect(object sender, Gvitech.CityMaker.Controls._IRenderControlEvents_RcMouseClickSelectEvent e)
  20. {
  21. IPickResult pr = e.pickResult as IPickResult;
  22. IPoint point = e.intersectPoint;
  23. if (pr == null)
  24. return;
  25. //点击类型
  26. if (e.eventSender == gviMouseSelectMode.gviMouseSelectClick)
  27. {
  28. var vec = point.Position;
  29. if (clickNum == 0)
  30. {
  31. IPosition position = new Position();//初始化位置
  32. //设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)
  33. position.Init(point.X, point.Y, point.Z, 0, 0, 0, gviAltitudeType.gviAltitudeTerrainAbsolute);
  34. position.distance=500;//相机飞到位置时,position距离相机的距离
  35. //创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)
  36. rBox = rendercontrol.ObjectManager.CreateBox(position, 0.1, 0.1, 0.1, 0xffcccccc, 0xffcccccc, rootId);
  37. clickNum = 1;
  38. point1 = point;
  39. var screen1 = rendercontrol.Camera.WorldToScreen(point.X, point.Y, point.Z, out ScreenX1, out ScreenY1, 1, out b);
  40. }
  41. else if (clickNum == 1)
  42. {
  43. //通过获取到的鼠标坐标点转换成屏幕点
  44. var screen2 = rendercontrol.Camera.WorldToScreen(point.X, point.Y, point.Z, out ScreenX2, out ScreenY2, 1, out b);
  45. point2 = point;
  46. clickNum = 2;
  47. }
  48. else if (clickNum == 2)
  49. {
  50. rendercontrol.RcMouseClickSelect -= new Gvitech.CityMaker.Controls._IRenderControlEvents_RcMouseClickSelectEventHandler(RcMouseClickSelect);
  51. clickNum = 0;
  52. }
  53. //移动鼠标类型时
  54. }
  55. else if (e.eventSender == gviMouseSelectMode.gviMouseSelectMove)
  56. {
  57. if (clickNum == 1)
  58. {
  59. //改变右下角坐标
  60. rBox.Bottom = point.Y;
  61. rBox.Right = point.X;
  62. }
  63. else if (clickNum == 2)
  64. {
  65. //通过获取到的鼠标坐标点转换成屏幕点
  66. double ScreenX = 0.0;
  67. double ScreenY = 0.0;
  68. var screen = rendercontrol.Camera.WorldToScreen(point.X, point.Y, point.Z, out ScreenX, out ScreenY, 1, out b);
  69. var vecxy2 = (point2.Position.X - point1.Position.X) * (point2.Position.X - point1.Position.X);
  70. var vecxy22 = Math.Sqrt(vecxy2);
  71. var vecxyS = (ScreenY2 - ScreenY1) * (ScreenY2 - ScreenY1) + (ScreenX2 - ScreenX1) * (ScreenX2 - ScreenX1);
  72. var vecxySS = Math.Sqrt(vecxyS);
  73. //实时改变高度 实时高度是第一点的x坐标到第二点的x坐标距离跟两点像素比例等于第二点跟移动点高度比例
  74. rBox.Height = (ScreenY2 - ScreenY) * vecxy22 / vecxySS;
  75. }
  76. }
  77. }

2. JavaScript

基础方法

  1. function createRenderObject()
  2. {
  3. //获取三维根节点
  4. var __rootId = __g.objectManager.getProjectTree().rootID;
  5. //初始化一个位置对象position
  6. var position = __g.new_Position;
  7. //设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)
  8. position.init(10,10,0,0,0,0,gviAltitudeType.gviAltitudeTerrainRelative);
  9. position.distance=500;//相机飞到位置时,position距离相机的距离
  10. //创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)
  11. var rBox=__g.objectManager.createBox(position,100,50,50,0xffcccccc,0xffcccccc,__rootId);
  12. //设置相机飞到线对象
  13. __g.camera.flyToObject(rBox.guid,gviActionCode.gviActionFlyTo);
  14. //创建球 参数为(位置position对象,半径、显示球类型(0、1、2、3、4分别表示显示全显示、上半部分、下半部分、上半部分包括底面、下半部分包括顶面)
  15. //线框颜色、填充颜色、网格的密度(用来表示球的密度)、组节点guid)
  16. var rSphere = __g.objectManager.createSphere(position, 20, 3,0xffcccccc, 0xFF808080, 10,__rootId);
  17. __g.camera.flyToObject(rSphere.guid,gviActionCode.gviActionFlyTo);
  18. //创建圆柱 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)
  19. var rCylinder = __g.objectManager.createCylinder(position, 20, 123,0xff1295EE, 0xFF808080, 100,__rootId);
  20. __g.camera.flyToObject(rCylinder.guid,gviActionCode.gviActionFlyTo);
  21. //创建圆锥 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)
  22. var rCone = __g.objectManager.createCone(position, 20, -123,0xff1295EE, 0xFF808080, 100,__rootId);
  23. __g.camera.flyToObject(rCone.guid,gviActionCode.gviActionFlyTo);
  24. }

实时绘制立方体

  1. function createBox(){
  2. //设置交互模型、拾取对象、选取模型,注册事件
  3. __g.interactMode = gviInteractMode.gviInteractSelect;
  4. //MouseSelectMode与MouseSelectObjectMask之间的调用不存在顺序问题。
  5. __g.mouseSelectObjectMask = gviMouseSelectObjectMask.gviSelectAll;
  6. __g.mouseSelectMode = gviMouseSelectMode.gviMouseSelectClick| gviMouseSelectMode.gviMouseSelectMove;
  7. __g.onmouseclickselect = fnonmouseclickselect;
  8. }
  9. var clickNum=0;//点击的次数
  10. var rBox;//box对象
  11. //第一个点击点和第二个点击点 屏幕坐标x、y 和实际坐标
  12. var screenX1,screenX2,screenY1,screenY2,point1,point2;
  13. //单击事件 返回值 (相交得到的对象、相交点、判断是否多键按下枚举值、事件发出者)
  14. function fnonmouseclickselect(pickResult, intersectPoint, mask, eventSender){
  15. if (intersectPoint == null)
  16. return;
  17. //点击类型时
  18. if (eventSender == gviMouseSelectMode.gviMouseSelectClick) {
  19. if(clickNum==0){
  20. var vec=intersectPoint.position;
  21. var position = __g.new_Position;
  22. //设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)
  23. position.init(intersectPoint.x,intersectPoint.y,intersectPoint.z,0,0,0,gviAltitudeType.gviAltitudeTerrainAbsolute);
  24. position.distance=500;//相机飞到位置时,position距离相机的距离
  25. //创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)
  26. rBox=__g.objectManager.createBox(position,0.1,0.1,0.1,0xffcccccc,0xffcccccc,__rootId);
  27. clickNum=1;
  28. point1=intersectPoint;
  29. var screen1=__g.camera.worldToScreen(intersectPoint.x,intersectPoint.y,intersectPoint.z,0);
  30. screenX1=screen1.screenX;
  31. screenY1=screen1.screenY;
  32. }else if(clickNum==1){
  33. //通过获取到的鼠标坐标点转换成屏幕点
  34. var screen2=__g.camera.worldToScreen(intersectPoint.x,intersectPoint.y,intersectPoint.z,0);
  35. screenX2=screen2.screenX;
  36. screenY2=screen2.screenY;
  37. point2=intersectPoint;
  38. clickNum=2;
  39. }else if(clickNum==2){
  40. __g.onmouseclickselect = "";
  41. clickNum=0;
  42. }
  43. //移动鼠标类型时
  44. } else if (eventSender == gviMouseSelectMode.gviMouseSelectMove) {
  45. if(clickNum==1){
  46. //改变右下角坐标
  47. rBox.bottom=intersectPoint.y;
  48. rBox.right=intersectPoint.x;
  49. }else if(clickNum==2){
  50. //通过获取到的鼠标坐标点转换成屏幕点
  51. var screen=__g.camera.worldToScreen(intersectPoint.x,intersectPoint.y,intersectPoint.z,0);
  52. var screenY3=screen.screenY;
  53. var vecxy2 = (point2.position.x - point1.position.x) * (point2.position.x - point1.position.x);
  54. var vecxy22 = Math.sqrt(vecxy2);
  55. var vecxyS = (screenY2 - screenY1) * (screenY2 - screenY1) + (screenX2 - screenX1) * (screenX2 - screenX1);
  56. var vecxySS = Math.sqrt(vecxyS);
  57. //实时改变高度 //实时改变高度 实时高度是第一点的x坐标到第二点的x坐标距离跟两点像素比例等于第二点跟移动点高度比例
  58. rBox.height=(screenY2 - screenY3) * vecxy22 / vecxySS;
  59. }
  60. }
  61. }

3. 注意

  1. 创建体用到的是position对象,非vector对象。
  2. 设置position距离,相机到该点的距离,如果不设置会很近。
  3. 这些对象都不需要创建对应的几何再可视化,而是通过位置点以及参数和样式来创建可视化对象。
  4. 球、立方体、圆柱等都是由三角面组成的,有fillstyle属性可以设置贴图纹理,不过暂未实现。