如何获得P5.js的球体交点?
How to get sphere intersection points with P5.js?
我正在使用 p5.js 创建一个 sphere
我感兴趣的是获取用于对球体建模的形状的点坐标。
可以吗?
基本上,我想获得用于绘制对球体建模的三角形的一系列点。
您可以使用 spherical coordinates(两个角度和半径)到笛卡尔坐标 (x,y,z) 的转换公式来计算球体上的点:
(图片来源:维基百科)
如果你把这两个角度想象成我们地球上的纬度(lat
)、经度(lon
)角度和一个恒定的半径,在JS中你可以把这个公式看成:
var x = radius * cos(lat) * sin(lon);
var y = radius * sin(lat) * sin(lon);
var z = radius * cos(lon);
这里有一个基本的草图来说明这个想法:
var radius = 120;
var latDetail = 0.243;
var lonDetail = 0.15;
function setup() {
createCanvas(300, 300, WEBGL);
strokeWeight(9);
}
function draw() {
background(255);
orbitControl();
beginShape(POINTS);
// iterate through lat, lon angles (in radians)
for(var lat = 0; lat <= PI; lat += latDetail){
for(var lon = 0; lon <= TWO_PI; lon += lonDetail){
// for each sperical coordinate (lat, lon angles, radius)
// convert to cartesian (x, y, z)
var x = radius * cos(lat) * sin(lon);
var y = radius * sin(lat) * sin(lon);
var z = radius * cos(lon);
// render each point
vertex(x, y, z);
}
}
endShape();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
玩一玩 latDetail, lonDetail
变量,这些变量定义 dense/sparse 球体的 parallels/meridians 将如何。
在线快速查看 UV 球体,Daniel Sieger's Generating Spheres article 非常棒!
虽然是c++的代码,但是语法很相似,可以看懂:
// generate vertices per stack / slice
for (int i = 0; i < n_stacks - 1; i++)
{
auto phi = M_PI * double(i + 1) / double(n_stacks);
for (int j = 0; j < n_slices; j++)
{
auto theta = 2.0 * M_PI * double(j) / double(n_slices);
auto x = std::sin(phi) * std::cos(theta);
auto y = std::cos(phi);
auto z = std::sin(phi) * std::sin(theta);
mesh.add_vertex(Point(x, y, z));
}
}
几乎相同的公式(没有 radius
标量)和每个角度上的段数的计数器(而不是角度增量)。
这是一个 p5.js 端口:
var radius = 120;
var uSegments = 12;
var vSegments = 12;
// sliders
var uSegmentsSlider;
var vSegmentsSlider;
function setup() {
createCanvas(300, 300, WEBGL);
strokeWeight(9);
uSegmentsSlider = createSlider(3, 36, 12, 1);
vSegmentsSlider = createSlider(3, 36, 12, 1);
uSegmentsSlider.position(10, 10);
vSegmentsSlider.position(10, 30);
createP('U').position(145, -3);
createP('V').position(145, 17);
}
function draw() {
// read slider values
uSegments = uSegmentsSlider.value();
vSegments = vSegmentsSlider.value();
background(255);
orbitControl();
beginShape(POINTS);
// iterate through u, v segments
for(var u = 0; u < uSegments; u++){
var phi = PI * (u + 1) / uSegments;
for(var v = 0; v < vSegments; v++){
var theta = TWO_PI * v / vSegments;
// for each sperical coordinate (lat, lon angles, radius)
// convert to cartesian (x, y, z)
var x = radius * cos(theta) * sin(phi);
var y = radius * sin(theta) * sin(phi);
var z = radius * cos(phi);
// render each point
vertex(x, y, z);
}
}
endShape();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
我正在使用 p5.js 创建一个 sphere
我感兴趣的是获取用于对球体建模的形状的点坐标。
可以吗?
基本上,我想获得用于绘制对球体建模的三角形的一系列点。
您可以使用 spherical coordinates(两个角度和半径)到笛卡尔坐标 (x,y,z) 的转换公式来计算球体上的点:
(图片来源:维基百科)
如果你把这两个角度想象成我们地球上的纬度(lat
)、经度(lon
)角度和一个恒定的半径,在JS中你可以把这个公式看成:
var x = radius * cos(lat) * sin(lon);
var y = radius * sin(lat) * sin(lon);
var z = radius * cos(lon);
这里有一个基本的草图来说明这个想法:
var radius = 120;
var latDetail = 0.243;
var lonDetail = 0.15;
function setup() {
createCanvas(300, 300, WEBGL);
strokeWeight(9);
}
function draw() {
background(255);
orbitControl();
beginShape(POINTS);
// iterate through lat, lon angles (in radians)
for(var lat = 0; lat <= PI; lat += latDetail){
for(var lon = 0; lon <= TWO_PI; lon += lonDetail){
// for each sperical coordinate (lat, lon angles, radius)
// convert to cartesian (x, y, z)
var x = radius * cos(lat) * sin(lon);
var y = radius * sin(lat) * sin(lon);
var z = radius * cos(lon);
// render each point
vertex(x, y, z);
}
}
endShape();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
玩一玩 latDetail, lonDetail
变量,这些变量定义 dense/sparse 球体的 parallels/meridians 将如何。
在线快速查看 UV 球体,Daniel Sieger's Generating Spheres article 非常棒!
虽然是c++的代码,但是语法很相似,可以看懂:
// generate vertices per stack / slice
for (int i = 0; i < n_stacks - 1; i++)
{
auto phi = M_PI * double(i + 1) / double(n_stacks);
for (int j = 0; j < n_slices; j++)
{
auto theta = 2.0 * M_PI * double(j) / double(n_slices);
auto x = std::sin(phi) * std::cos(theta);
auto y = std::cos(phi);
auto z = std::sin(phi) * std::sin(theta);
mesh.add_vertex(Point(x, y, z));
}
}
几乎相同的公式(没有 radius
标量)和每个角度上的段数的计数器(而不是角度增量)。
这是一个 p5.js 端口:
var radius = 120;
var uSegments = 12;
var vSegments = 12;
// sliders
var uSegmentsSlider;
var vSegmentsSlider;
function setup() {
createCanvas(300, 300, WEBGL);
strokeWeight(9);
uSegmentsSlider = createSlider(3, 36, 12, 1);
vSegmentsSlider = createSlider(3, 36, 12, 1);
uSegmentsSlider.position(10, 10);
vSegmentsSlider.position(10, 30);
createP('U').position(145, -3);
createP('V').position(145, 17);
}
function draw() {
// read slider values
uSegments = uSegmentsSlider.value();
vSegments = vSegmentsSlider.value();
background(255);
orbitControl();
beginShape(POINTS);
// iterate through u, v segments
for(var u = 0; u < uSegments; u++){
var phi = PI * (u + 1) / uSegments;
for(var v = 0; v < vSegments; v++){
var theta = TWO_PI * v / vSegments;
// for each sperical coordinate (lat, lon angles, radius)
// convert to cartesian (x, y, z)
var x = radius * cos(theta) * sin(phi);
var y = radius * sin(theta) * sin(phi);
var z = radius * cos(phi);
// render each point
vertex(x, y, z);
}
}
endShape();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>