14

我正在尝试绘制一个与网站上的轨道图案非常相似的圆圈。我想使用 Three.js 而不是纯 WebGL。

4

9 回答 9

28

三.js r50 添加CircleGeometry。它可以在WebGL 几何示例中看到(尽管有一张脸) 。

几何中的第一个顶点是在圆的中心创建的(在 r84 中,请参见CircleGeometry.js 第 71 行,在 r65 中,请参见CircleGeometry.js 第 18 行),如果您要使用“完整的吃豆人”,这很不错”或“无信息饼图”的样子。哦,如果您要使用除LineBasicMaterial/之外的任何材料,这似乎是必要的LineDashedMaterial

我已验证以下代码适用于 r60 和 r65:

var radius   = 100,
    segments = 64,
    material = new THREE.LineBasicMaterial( { color: 0x0000ff } ),
    geometry = new THREE.CircleGeometry( radius, segments );

// Remove center vertex
geometry.vertices.shift();

// Non closed circle with one open segment:
scene.add( new THREE.Line( geometry, material ) );

// To get a closed circle use LineLoop instead (see also @jackrugile his comment):
scene.add( new THREE.LineLoop( geometry, material ) );

PS:“文档”现在包含一个很好的CircleGeometry交互式示例:https ://threejs.org/docs/#api/geometries/CircleGeometry

于 2014-02-12T23:29:15.113 回答
12

在threejs 的较新版本中,API 略有变化。

var segmentCount = 32,
    radius = 100,
    geometry = new THREE.Geometry(),
    material = new THREE.LineBasicMaterial({ color: 0xFFFFFF });

for (var i = 0; i <= segmentCount; i++) {
    var theta = (i / segmentCount) * Math.PI * 2;
    geometry.vertices.push(
        new THREE.Vector3(
            Math.cos(theta) * radius,
            Math.sin(theta) * radius,
            0));            
}

scene.add(new THREE.Line(geometry, material));

根据场景的需要进行修改segmentCount以使圆更平滑或更锯齿。对于小圆圈,32 段将非常平滑。对于您链接的网站上的轨道,您可能需要几百个。

修改Vector3构造函数中三个组件的顺序以选择圆的方向。如此处给出的,圆将与 x/y 平面对齐。

于 2013-12-19T23:04:08.290 回答
4

我使用了这个 github 帖子中 Mr.doob 引用的代码。

var resolution = 100;
var amplitude = 100;
var size = 360 / resolution;

var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { color: 0xFFFFFF, opacity: 1.0} );
for(var i = 0; i <= resolution; i++) {
    var segment = ( i * size ) * Math.PI / 180;
    geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( Math.cos( segment ) * amplitude, 0, Math.sin( segment ) * amplitude ) ) );         
}

var line = new THREE.Line( geometry, material );
scene.add(line);
于 2012-12-08T01:11:48.513 回答
4

此示例在 Three.js 文档中:

var material = new THREE.MeshBasicMaterial({
    color: 0x0000ff
});

var radius = 5;
var segments = 32; //<-- Increase or decrease for more resolution I guess

var circleGeometry = new THREE.CircleGeometry( radius, segments );              
var circle = new THREE.Mesh( circleGeometry, material );
scene.add( circle );
于 2014-04-19T17:08:42.473 回答
2

我不得不这样做大声笑:

function createCircle() {
    let circleGeometry = new THREE.CircleGeometry(1.0, 30.0);
    circleGeometry.vertices.splice(0, 1); //<= This.
    return new THREE.LineLoop(circleGeometry,
        new THREE.LineBasicMaterial({ color: 'blue' }));
}
let circle = createCircle();

原因:否则,它不会绘制“纯”圆,即使您使用 LineLoop 而不是 Line ,也会有一条从圆心到圆边缘的线。从数组中拼接(删除)第一个顶点是一种技巧,但似乎可以解决问题。:)

(请注意,显然,根据mrienstra 的回答,“哦,如果您要使用 LineBasicMaterial / LineDashedMaterial 之外的任何材料,这似乎是必要的。”)


但是,如果您想要厚度,那您就完蛋了(“由于大多数平台上带有 WebGL 渲染器的 OpenGL 核心配置文件的限制,无论设置值如何,线宽始终为 1。”)...除非您使用:https: //github.com/spite/THREE.MeshLine

代码示例在这里:https ://stackoverflow.com/a/61312721/1599699

于 2020-04-19T21:45:33.970 回答
1

请参阅 three.js 示例http://mrdoob.github.com/three.js/examples/webgl_lines_colors.html以了解如何绘制彩色线条。

像您引用的那样的圆圈被绘制为大的#小直线段。(其实你显示的可能是省略号)

于 2012-12-07T06:01:20.537 回答
1
var getStuffDashCircle2 = function () {

var segment = 100, radius = 100;

var lineGeometry = new THREE.Geometry();
var vertArray = lineGeometry.vertices;
var angle = 2 * Math.PI / segment;
for (var i = 0; i < segment; i++) {
    var x = radius * Math.cos(angle * i);
    var y = radius * Math.sin(angle * i);
    vertArray.push(new THREE.Vector3(x, y, 0));
}
lineGeometry.computeLineDistances();
var lineMaterial = new THREE.LineDashedMaterial({ color: 0x00cc00, dashSize: 4, gapSize: 2 });
var circle = new THREE.Line(lineGeometry, lineMaterial);

circle.rotation.x = Math.PI / 2;
circle.position.y = cylinderParam.trackHeight+20;
return   circle;
}
于 2014-04-24T13:27:38.500 回答
0

我在这里获得其他答案时遇到了一些问题——特别是CircleGeometry在圆的中心有一个额外的点,而且我不喜欢试图删除那个顶点的黑客行为。

EllipseCurve做我想要的(在 r135 中验证):

const curve = new THREE.EllipseCurve(
  0.0, 0.0,            // Center x, y
  10.0, 10.0,          // x radius, y radius
  0.0, 2.0 * Math.PI,  // Start angle, stop angle
);

const pts = curve.getSpacedPoints(256);
const geo = new THREE.BufferGeometry().setFromPoints(pts);

const mat = new THREE.LineBasicMaterial({ color: 0xFF00FF });
const circle = new THREE.LineLoop(geo, mat);
scene.add(circle);
于 2021-12-23T19:04:10.467 回答
0

好吧,我不知道他们什么时候添加的——但是 TorusGeometry 应该可以完成这项工作…… 三个 TorusGeometry三环面几何

const geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const torus = new THREE.Mesh( geometry, material );
scene.add( torus );

不知道,但我认为它不应该比生产线贵(很多),而且它是一种缓冲几何形状,您可以调整尺寸和材料等...

于 2022-02-27T12:28:18.897 回答