一、技术原理
CityMaker创建体,原理是由点生成线,由线生成面,由面生成体,在三维中都是根据一个点坐标和一些条件(长宽或半径、颜色样式等)来生成体对象,根据视觉可以把体分为:立方体、球、圆锥、圆柱。
接口:
- 立方体:CreateBox
- 球:CreateSphere
- 圆柱:CreateCylinder
- 圆锥:CreateCone
方法:
一种是通过传入指定的坐标,第二种是实时绘制,例如长方体,可以点击第一个点 创建出来长方体,然后实时移动鼠标的时候更改 右下角x、y点坐标,单击第二个点,确定底面,然后移动位置 更改高度,单击第三个点创建改变高度参数即可
二、创建体
1. .NET
基础方法
public void CreateBox() {//初始化一个位置对象positionIPosition position = new Position();//设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)position.Init(10, 10, 0, 0, 0, 0, gviAltitudeType.gviAltitudeTerrainRelative);position.Distance = 500;//创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)var rBox = rendercontrol.ObjectManager.CreateBox(position, 100, 50, 50, 0xffcccccc, 0xffcccccc, __rootId);//设置相机飞到线对象rendercontrol.Camera.FlyToObject(rBox.Guid,gviActionCode.gviActionFlyTo);//创建圆柱 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)var rCylinder = rendercontrol.ObjectManager.CreateCylinder(position, 20, 123, 0xff1295EE, 0xFF808080, 100, __rootId);rendercontrol.Camera.FlyToObject(rCylinder.Guid, gviActionCode.gviActionFlyTo);//创建圆锥 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)var rCone = rendercontrol.ObjectManager.CreateCone(position, 20, -123, 0xff1295EE, 0xFF808080, 100, __rootId);rendercontrol.Camera.FlyToObject(rCone.Guid, gviActionCode.gviActionFlyTo);//创建球 参数为(位置position对象,半径、显示球类型(0、1、2、3、4分别表示显示全显示、上半部分、下半部分、上半部分包括底面、下半部分包括顶面)、//线框颜色、填充颜色、网格的密度(用来表示球的密度)、组节点guid)var rSphere = rendercontrol.ObjectManager.CreateSphere(position, 20, 3, 0xffcccccc, 0xFF808080, 10, __rootId);rendercontrol.Camera.FlyToObject(rSphere.Guid, gviActionCode.gviActionFlyTo);}
实时绘制立方体
public void Create(){// 注册控件拾取事件this.rendercontrol.RcMouseClickSelect += new Gvitech.CityMaker.Controls._IRenderControlEvents_RcMouseClickSelectEventHandler(RcMouseClickSelect);this.rendercontrol.InteractMode = gviInteractMode.gviInteractSelect;this.rendercontrol.MouseSelectObjectMask = gviMouseSelectObjectMask.gviSelectAll;this.rendercontrol.MouseSelectMode = gviMouseSelectMode.gviMouseSelectClick | gviMouseSelectMode.gviMouseSelectMove;}double clickNum = 0;//点击的次数ITerrain3DRectBase rBox;//立方体对象double ScreenX1 = 0.0;//第一个点的屏幕坐标double ScreenY1 = 0.0;double ScreenX2 = 0.0;//第二个点的屏幕坐标double ScreenY2 = 0.0;IPoint point1;//实际第一个点IPoint point2;//实际第二个点bool b = false;//点击事件public void RcMouseClickSelect(object sender, Gvitech.CityMaker.Controls._IRenderControlEvents_RcMouseClickSelectEvent e){IPickResult pr = e.pickResult as IPickResult;IPoint point = e.intersectPoint;if (pr == null)return;//点击类型if (e.eventSender == gviMouseSelectMode.gviMouseSelectClick){var vec = point.Position;if (clickNum == 0){IPosition position = new Position();//初始化位置//设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)position.Init(point.X, point.Y, point.Z, 0, 0, 0, gviAltitudeType.gviAltitudeTerrainAbsolute);position.distance=500;//相机飞到位置时,position距离相机的距离//创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)rBox = rendercontrol.ObjectManager.CreateBox(position, 0.1, 0.1, 0.1, 0xffcccccc, 0xffcccccc, rootId);clickNum = 1;point1 = point;var screen1 = rendercontrol.Camera.WorldToScreen(point.X, point.Y, point.Z, out ScreenX1, out ScreenY1, 1, out b);}else if (clickNum == 1){//通过获取到的鼠标坐标点转换成屏幕点var screen2 = rendercontrol.Camera.WorldToScreen(point.X, point.Y, point.Z, out ScreenX2, out ScreenY2, 1, out b);point2 = point;clickNum = 2;}else if (clickNum == 2){rendercontrol.RcMouseClickSelect -= new Gvitech.CityMaker.Controls._IRenderControlEvents_RcMouseClickSelectEventHandler(RcMouseClickSelect);clickNum = 0;}//移动鼠标类型时}else if (e.eventSender == gviMouseSelectMode.gviMouseSelectMove){if (clickNum == 1){//改变右下角坐标rBox.Bottom = point.Y;rBox.Right = point.X;}else if (clickNum == 2){//通过获取到的鼠标坐标点转换成屏幕点double ScreenX = 0.0;double ScreenY = 0.0;var screen = rendercontrol.Camera.WorldToScreen(point.X, point.Y, point.Z, out ScreenX, out ScreenY, 1, out b);var vecxy2 = (point2.Position.X - point1.Position.X) * (point2.Position.X - point1.Position.X);var vecxy22 = Math.Sqrt(vecxy2);var vecxyS = (ScreenY2 - ScreenY1) * (ScreenY2 - ScreenY1) + (ScreenX2 - ScreenX1) * (ScreenX2 - ScreenX1);var vecxySS = Math.Sqrt(vecxyS);//实时改变高度 实时高度是第一点的x坐标到第二点的x坐标距离跟两点像素比例等于第二点跟移动点高度比例rBox.Height = (ScreenY2 - ScreenY) * vecxy22 / vecxySS;}}}
2. JavaScript
基础方法
function createRenderObject(){//获取三维根节点var __rootId = __g.objectManager.getProjectTree().rootID;//初始化一个位置对象positionvar position = __g.new_Position;//设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)position.init(10,10,0,0,0,0,gviAltitudeType.gviAltitudeTerrainRelative);position.distance=500;//相机飞到位置时,position距离相机的距离//创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)var rBox=__g.objectManager.createBox(position,100,50,50,0xffcccccc,0xffcccccc,__rootId);//设置相机飞到线对象__g.camera.flyToObject(rBox.guid,gviActionCode.gviActionFlyTo);//创建球 参数为(位置position对象,半径、显示球类型(0、1、2、3、4分别表示显示全显示、上半部分、下半部分、上半部分包括底面、下半部分包括顶面)//线框颜色、填充颜色、网格的密度(用来表示球的密度)、组节点guid)var rSphere = __g.objectManager.createSphere(position, 20, 3,0xffcccccc, 0xFF808080, 10,__rootId);__g.camera.flyToObject(rSphere.guid,gviActionCode.gviActionFlyTo);//创建圆柱 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)var rCylinder = __g.objectManager.createCylinder(position, 20, 123,0xff1295EE, 0xFF808080, 100,__rootId);__g.camera.flyToObject(rCylinder.guid,gviActionCode.gviActionFlyTo);//创建圆锥 参数为(位置position对象,半径、高度、线框颜色、填充颜色、边数、组节点guid)var rCone = __g.objectManager.createCone(position, 20, -123,0xff1295EE, 0xFF808080, 100,__rootId);__g.camera.flyToObject(rCone.guid,gviActionCode.gviActionFlyTo);}
实时绘制立方体
function createBox(){//设置交互模型、拾取对象、选取模型,注册事件__g.interactMode = gviInteractMode.gviInteractSelect;//MouseSelectMode与MouseSelectObjectMask之间的调用不存在顺序问题。__g.mouseSelectObjectMask = gviMouseSelectObjectMask.gviSelectAll;__g.mouseSelectMode = gviMouseSelectMode.gviMouseSelectClick| gviMouseSelectMode.gviMouseSelectMove;__g.onmouseclickselect = fnonmouseclickselect;}var clickNum=0;//点击的次数var rBox;//box对象//第一个点击点和第二个点击点 屏幕坐标x、y 和实际坐标var screenX1,screenX2,screenY1,screenY2,point1,point2;//单击事件 返回值 (相交得到的对象、相交点、判断是否多键按下枚举值、事件发出者)function fnonmouseclickselect(pickResult, intersectPoint, mask, eventSender){if (intersectPoint == null)return;//点击类型时if (eventSender == gviMouseSelectMode.gviMouseSelectClick) {if(clickNum==0){var vec=intersectPoint.position;var position = __g.new_Position;//设置 位置的x、y坐标、高度、方向角、上下旋转角、自身旋转角,gviAltitudeType为高程类型包括(绝对地形、相对地形、贴地、相对轴)position.init(intersectPoint.x,intersectPoint.y,intersectPoint.z,0,0,0,gviAltitudeType.gviAltitudeTerrainAbsolute);position.distance=500;//相机飞到位置时,position距离相机的距离//创建立方体 参数为(位置position对象,宽度、深度、高度、线框颜色、填充颜色、组节点guid)rBox=__g.objectManager.createBox(position,0.1,0.1,0.1,0xffcccccc,0xffcccccc,__rootId);clickNum=1;point1=intersectPoint;var screen1=__g.camera.worldToScreen(intersectPoint.x,intersectPoint.y,intersectPoint.z,0);screenX1=screen1.screenX;screenY1=screen1.screenY;}else if(clickNum==1){//通过获取到的鼠标坐标点转换成屏幕点var screen2=__g.camera.worldToScreen(intersectPoint.x,intersectPoint.y,intersectPoint.z,0);screenX2=screen2.screenX;screenY2=screen2.screenY;point2=intersectPoint;clickNum=2;}else if(clickNum==2){__g.onmouseclickselect = "";clickNum=0;}//移动鼠标类型时} else if (eventSender == gviMouseSelectMode.gviMouseSelectMove) {if(clickNum==1){//改变右下角坐标rBox.bottom=intersectPoint.y;rBox.right=intersectPoint.x;}else if(clickNum==2){//通过获取到的鼠标坐标点转换成屏幕点var screen=__g.camera.worldToScreen(intersectPoint.x,intersectPoint.y,intersectPoint.z,0);var screenY3=screen.screenY;var vecxy2 = (point2.position.x - point1.position.x) * (point2.position.x - point1.position.x);var vecxy22 = Math.sqrt(vecxy2);var vecxyS = (screenY2 - screenY1) * (screenY2 - screenY1) + (screenX2 - screenX1) * (screenX2 - screenX1);var vecxySS = Math.sqrt(vecxyS);//实时改变高度 //实时改变高度 实时高度是第一点的x坐标到第二点的x坐标距离跟两点像素比例等于第二点跟移动点高度比例rBox.height=(screenY2 - screenY3) * vecxy22 / vecxySS;}}}
3. 注意
- 创建体用到的是position对象,非vector对象。
- 设置position距离,相机到该点的距离,如果不设置会很近。
- 这些对象都不需要创建对应的几何再可视化,而是通过位置点以及参数和样式来创建可视化对象。
- 球、立方体、圆柱等都是由三角面组成的,有fillstyle属性可以设置贴图纹理,不过暂未实现。
