一、技术原理
CityMaker创建体,原理是由点生成线,由线生成面,由面生成体,在三维中都是根据一个点坐标和一些条件(长宽或半径、颜色样式等)来生成体对象,根据视觉可以把体分为:立方体、球、圆锥、圆柱。
接口:
- 立方体:CreateBox
- 球:CreateSphere
- 圆柱:CreateCylinder
- 圆锥:CreateCone
方法:
一种是通过传入指定的坐标,第二种是实时绘制,例如长方体,可以点击第一个点 创建出来长方体,然后实时移动鼠标的时候更改 右下角x、y点坐标,单击第二个点,确定底面,然后移动位置 更改高度,单击第三个点创建改变高度参数即可
二、创建体
1. .NET
基础方法
public void CreateBox() {
//初始化一个位置对象position
IPosition 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;
//初始化一个位置对象position
var 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属性可以设置贴图纹理,不过暂未实现。