# cesium 圆锥体绕某一个点翻转一个角度如何实现

###### 问题相关代码，请勿粘贴截图
``````            var positioncone = Cesium.Cartesian3.fromDegrees(locs[0], locs[1], locs[2]/2)
var position = Cesium.Cartesian3.fromDegrees(locs[0], locs[1], locs[2])
//镜头对准方法：
position,
hprcone
);
name: 'Red cone',
position: positioncone,
orientation: orientationcone,
cylinder: {
length: locs[2],
material: Cesium.Color.BLUE.withAlpha(0.9),
disableDepthTestDistance: 0,
},
});
``````
###### 我的解答思路和尝试过的方法

origin设置为（[0], [1], [2]）没用，圆锥还是绕着它自己的中心点旋转

• 写回答

#### 2条回答默认 最新

• 前端人丶 2022-04-10 13:11
关注

几何体旋转都是以几何原点为基准旋转的 cesium提供的圆锥体几何原点是几何体中心不是圆锥顶点,这里可以使用primitive-geometry重新构建出以顶点为原点的几何体进行绘制 然后进行旋转变换;
提供一个我仿照cesium圆锥构建的类
`
import { BoundingSphere, Cartesian2, Cartesian3, Math as CesiumMath, defaultValue, defined, DeveloperError, Geometry, Primitive, PrimitiveType, VertexFormat, GeometryAttribute, ComponentDatatype, IndexDatatype, GeometryAttributes } from "cesium";
function arrayFill(array: any[] | Uint8Array, value: any, start?: number, end?: number) {
if (typeof array.fill === "function") {
return array.fill(value, start, end);
}

const length = array.length >>> 0;
const relativeStart = defaultValue(start, 0);
// If negative, find wrap around position
let k =
relativeStart < 0
? Math.max(length + relativeStart, 0)
: Math.min(relativeStart, length);
const relativeEnd = defaultValue(end, length);
// If negative, find wrap around position
const last =
relativeEnd < 0
? Math.max(length + relativeEnd, 0)
: Math.min(relativeEnd, length);

// Fill array accordingly
while (k < last) {
array[k] = value;
k++;
}
return array;
}

function computePositions(length: number, topRadius: number, bottomRadius: number, slices: number, fill: boolean) {
const topZ = 0;
const bottomZ = -length;

const twoSlice = slices + slices;
const size = fill ? 2 * twoSlice : twoSlice;
const positions = new Float64Array(size * 3);
let i;
let index = 0;
let tbIndex = 0;
const bottomOffset = fill ? twoSlice * 3 : 0;
const topOffset = fill ? (twoSlice + slices) * 3 : slices * 3;

for (i = 0; i < slices; i++) {
const angle = (i / slices) * CesiumMath.TWO_PI;
const x = Math.cos(angle);
const y = Math.sin(angle);
const bottomX = x * bottomRadius;
const bottomY = y * bottomRadius;
const topX = x * topRadius;
const topY = y * topRadius;

``````positions[tbIndex + bottomOffset] = bottomX;
positions[tbIndex + bottomOffset + 1] = bottomY;
positions[tbIndex + bottomOffset + 2] = bottomZ;

positions[tbIndex + topOffset] = topX;
positions[tbIndex + topOffset + 1] = topY;
positions[tbIndex + topOffset + 2] = topZ;
tbIndex += 3;
if (fill) {
positions[index++] = bottomX;
positions[index++] = bottomY;
positions[index++] = bottomZ;
positions[index++] = topX;
positions[index++] = topY;
positions[index++] = topZ;
}
``````

}

return positions;
};

type ConeGeometryOption = {
length: number;
slices?: number;
vertexFormat?: VertexFormat;
numberOfVerticalLines?: number;
offsetAttribute?: number;
}

function createGeometry(options: ConeGeometryOption) {
let length = options.length;
const vertexFormat = options.vertexFormat as VertexFormat;
const slices = options.slices as number;
const offsetAttribute = options.offsetAttribute;

if (
length <= 0 ||
) {
return;
}

const twoSlices = slices + slices;
const threeSlices = slices + twoSlices;
const numVertices = twoSlices + twoSlices;

const st = vertexFormat.st ? new Float32Array(numVertices * 2) : undefined;
const normals = vertexFormat.normal ? new Float32Array(numVertices * 3) : undefined;
const tangents = vertexFormat.tangent ? new Float32Array(numVertices * 3) : undefined;
const bitangents = vertexFormat.bitangent ? new Float32Array(numVertices * 3) : undefined;

let i;
const computeNormal = vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent;

if (computeNormal) {
const computeTangent = vertexFormat.tangent || vertexFormat.bitangent;

``````let normalIndex = 0;
let tangentIndex = 0;
let bitangentIndex = 0;

const normal = new Cartesian3();
normal.z = Math.sin(theta);
const normalScale = Math.cos(theta);
let tangent = new Cartesian3();
let bitangent = new Cartesian3();

for (i = 0; i < slices; i++) {
const angle = (i / slices) * CesiumMath.TWO_PI;
const x = normalScale * Math.cos(angle);
const y = normalScale * Math.sin(angle);
if (computeNormal) {
normal.x = x;
normal.y = y;

if (computeTangent) {
tangent = Cartesian3.normalize(
Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent),
tangent
);
}

if (normals) {
normals[normalIndex++] = normal.x;
normals[normalIndex++] = normal.y;
normals[normalIndex++] = normal.z;
normals[normalIndex++] = normal.x;
normals[normalIndex++] = normal.y;
normals[normalIndex++] = normal.z;
}

if (tangents) {
tangents[tangentIndex++] = tangent.x;
tangents[tangentIndex++] = tangent.y;
tangents[tangentIndex++] = tangent.z;
tangents[tangentIndex++] = tangent.x;
tangents[tangentIndex++] = tangent.y;
tangents[tangentIndex++] = tangent.z;
}

if (bitangents) {
bitangent = Cartesian3.normalize(
Cartesian3.cross(normal, tangent, bitangent),
bitangent
);
bitangents[bitangentIndex++] = bitangent.x;
bitangents[bitangentIndex++] = bitangent.y;
bitangents[bitangentIndex++] = bitangent.z;
bitangents[bitangentIndex++] = bitangent.x;
bitangents[bitangentIndex++] = bitangent.y;
bitangents[bitangentIndex++] = bitangent.z;
}
}
}

for (i = 0; i < slices; i++) {
if (normals) {
normals[normalIndex++] = 0;
normals[normalIndex++] = 0;
normals[normalIndex++] = -1;
}
if (tangents) {
tangents[tangentIndex++] = 1;
tangents[tangentIndex++] = 0;
tangents[tangentIndex++] = 0;
}
if (bitangents) {
bitangents[bitangentIndex++] = 0;
bitangents[bitangentIndex++] = -1;
bitangents[bitangentIndex++] = 0;
}
}

for (i = 0; i < slices; i++) {
if (normals) {
normals[normalIndex++] = 0;
normals[normalIndex++] = 0;
normals[normalIndex++] = 1;
}
if (tangents) {
tangents[tangentIndex++] = 1;
tangents[tangentIndex++] = 0;
tangents[tangentIndex++] = 0;
}
if (bitangents) {
bitangents[bitangentIndex++] = 0;
bitangents[bitangentIndex++] = 1;
bitangents[bitangentIndex++] = 0;
}
}
``````

}

const numIndices = 12 * slices - 12;

const indices = IndexDatatype.createTypedArray(numVertices, numIndices);
let index = 0;
let j = 0;
for (i = 0; i < slices - 1; i++) {
indices[index++] = j;
indices[index++] = j + 2;
indices[index++] = j + 3;

``````indices[index++] = j;
indices[index++] = j + 3;
indices[index++] = j + 1;

j += 2;
``````

}

indices[index++] = twoSlices - 2;
indices[index++] = 0;
indices[index++] = 1;
indices[index++] = twoSlices - 2;
indices[index++] = 1;
indices[index++] = twoSlices - 1;

for (i = 1; i < slices - 1; i++) {
indices[index++] = twoSlices + i + 1;
indices[index++] = twoSlices + i;
indices[index++] = twoSlices;
}

for (i = 1; i < slices - 1; i++) {
indices[index++] = threeSlices;
indices[index++] = threeSlices + i;
indices[index++] = threeSlices + i + 1;
}

let textureCoordIndex = 0;
if (st) {
for (i = 0; i < numVertices; i++) {

const position = Cartesian3.fromArray(positions, i * 3, new Cartesian3());
}
}

const attributes = new GeometryAttributes();
if (vertexFormat.position) {
attributes.position = new GeometryAttribute({
componentDatatype: ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: positions,
});
}

if (vertexFormat.normal) {
attributes.normal = new GeometryAttribute({
componentDatatype: ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: normals,
});
}

if (vertexFormat.tangent) {
attributes.tangent = new GeometryAttribute({
componentDatatype: ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: tangents,
});
}

if (vertexFormat.bitangent) {
attributes.bitangent = new GeometryAttribute({
componentDatatype: ComponentDatatype.FLOAT,
componentsPerAttribute: 3,
values: bitangents,
});
}

if (vertexFormat.st) {
attributes.st = new GeometryAttribute({
componentDatatype: ComponentDatatype.FLOAT,
componentsPerAttribute: 2,
values: st,
});
}

const boundingSphere = new BoundingSphere(
Cartesian3.ZERO,
);

if (defined(offsetAttribute)) {
length = positions.length;
const applyOffset = new Uint8Array(length / 3);
const offsetValue = offsetAttribute === 0 ? 0 : 1;
arrayFill(applyOffset, offsetValue);

attributes.applyOffset = new GeometryAttribute({
componentDatatype: ComponentDatatype.UNSIGNED_BYTE,
componentsPerAttribute: 1,
values: applyOffset,
});
}
return {
attributes: attributes,
indices: indices,
primitiveType: PrimitiveType.TRIANGLES,
boundingSphere: boundingSphere,

offsetAttribute: offsetAttribute,
};
}

/**

• 圆锥-ptimiotive
• 以顶点为中心圆锥
• /
class ConeGeometry extends Geometry {
constructor(options: ConeGeometryOption) {
options.slices = defaultValue(options.slices, 128);
const vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT);
options.vertexFormat = VertexFormat.clone(vertexFormat);
if (defined(options.offsetAttribute) && options.offsetAttribute === 1) {
``````throw new DeveloperError("GeometryOffsetAttribute.TOP is not a supported options.offsetAttribute for this geometry.");
``````
}
options.offsetAttribute = options.offsetAttribute;
const geometryOption = createGeometry(options) as {
``````attributes: GeometryAttributes;
primitiveType?: PrimitiveType;
indices?: Uint16Array | Uint32Array;
boundingSphere?: BoundingSphere;
``````
};
super(geometryOption);
}
}

export default ConeGeometry;

geometryInstances: new GeometryInstance({
geometry: new ConeGeometry({
length: 10000,
})
}),
modelMatrix: modelMatrix,
asynchronous: false,
appearance: new MaterialAppearance({
closed: true,
material: Material.fromType('Color', {
color: Color.RED
})
}),
}))
});

`

本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

• 系统已结题 4月18日
• 已采纳回答 4月10日
• 创建了问题 4月9日

#### 悬赏问题

• ¥15 网络爬虫 在北京新发地抓取数据
• ¥15 在centos7安装conda
• ¥15 c#调用yolo3 dll文件获取的数据对不上
• ¥20 WPF 如何实现多语言，label 和cs(live Charts)中是否都能翻译
• ¥15 STM32F103上电短路问题
• ¥15 关于#单片机#的问题：以ATMEGA128或相近型号单片机为控制器设计直流电机调速的闭环控制系统（相关搜索：设计报告|软件设计|流程图）
• ¥15 打开软件提示错误：failed to get wglChoosePixelFormatARB
• ¥15 (标签-python|关键词-char)
• ¥15 python+selenium，在新增时弹出了一个输入框
• ¥15 苹果验机结果的api接口哪里有？？单次调用1毛钱及以下。