Plotly.js 带 mesh3d 的球体
Plotly.js sphere with mesh3d
我正在尝试用 plotly.js 绘制一个简单的球体。然而,当使用 mesh3d 选项时,球体的图看起来非常粗糙和不精致。任何有关如何平滑它的建议将不胜感激。
a = [];
b = [];
c = [];
phiArr = [];
thetaArr = [];
function makeInterval(startValue, stopValue, numPoints) {
var arr = [];
var step = (stopValue - startValue) / (numPoints - 1);
for (var i = 0; i < numPoints; i++) {
arr.push(startValue + (step * i));
}
return arr;
}
phiArr = makeInterval(0, Math.PI, 20);
thetaArr = makeInterval(0, 2*Math.PI, 20);
for (i=0; i<thetaArr.length; i++){
for (j=0; j<phiArr.length; j++){
a.push(Math.cos(thetaArr[i]) * Math.sin(phiArr[j]));
b.push(Math.sin(thetaArr[i]) * Math.sin(phiArr[j]));
c.push(Math.cos(phiArr[j]));
}
}
var data = [{
opacity: 0.2,
color: 'rgb(211,211,211)',
type: 'mesh3d',
x: a,
y: b,
z: c,
}];
var layout = {
title: 'My Sphere',
autosize: false,
width: 600,
height: 600,
margin: {
l: 65,
r: 50,
b: 65,
t: 90,
}
};
Plotly.newPlot('myDiv', data, layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>
最简单的解决方案是绘制两个半球:
a = [];
b = [];
c = [];
phiArr = [];
thetaArr = [];
function makeInterval(startValue, stopValue, numPoints) {
var arr = [];
var step = (stopValue - startValue) / (numPoints - 1);
for (var i = 0; i < numPoints; i++) {
arr.push(startValue + (step * i));
}
return arr;
}
////////////////
// EDIT 1: calculate only upper half of the sphere
phiArr = makeInterval(0, Math.PI/2, 20);
///////////////
thetaArr = makeInterval(0, 2*Math.PI, 20);
for (i=0; i<thetaArr.length; i++){
for (j=0; j<phiArr.length; j++){
a.push(Math.cos(thetaArr[i]) * Math.sin(phiArr[j]));
b.push(Math.sin(thetaArr[i]) * Math.sin(phiArr[j]));
c.push(Math.cos(phiArr[j]));
}
}
const dataitem = {
opacity: 0.2,
color: 'rgb(211,211,211)',
type: 'mesh3d',
x: a,
y: b,
z: c,
}
//////////////////////
// EDIT 2: obtain the second half of the sphere by duplicating
// the upper semisphere ("..." operator before "dataitem") and
// changing its "z" attribute into negative vales:
var data = [
dataitem,
{...dataitem, z: c.map(v => -v)}
];
//////////////////////
var layout = {
title: 'My Sphere',
autosize: false,
width: 600,
height: 600,
margin: {
l: 65,
r: 50,
b: 65,
t: 90,
}
};
Plotly.newPlot('myDiv', data, layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>
来自@Josef Wittmann 的重要来源,这是一个可以复制到您的代码中的函数:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
</head>
<body>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script>
/////////////////////
function getSphereData(name, width, height, color, opacity) {
var layout = {
title: name,
autosize: false,
width: width,
height: height,
margin: {
l: 65,
r: 50,
b: 65,
t: 90,
}
};
a = [];
b = [];
c = [];
var phiArr = [];
var thetaArr = [];
var numPoints = 20;
var startValue = 0;
var stopValuePhi = Math.PI/2;
var stopValueTheta = 2*Math.PI;
var stepPhi = stopValuePhi / (numPoints - 1);
var stepTheta = stopValueTheta / (numPoints - 1);
for (var i = 0; i < numPoints; i++) {
phiArr.push(stepPhi * i);
thetaArr.push(stepTheta * i);
}
for (i=0; i<thetaArr.length; i++){
for (j=0; j<phiArr.length; j++){
a.push(Math.cos(thetaArr[i]) * Math.sin(phiArr[j]));
b.push(Math.sin(thetaArr[i]) * Math.sin(phiArr[j]));
c.push(Math.cos(phiArr[j]));
}
}
const dataitem = {
opacity: opacity,
color: 'rgb(211,211,211)',
type: 'mesh3d',
x: a,
y: b,
z: c,
}
// Obtain the second half of the sphere by
// duplicating the upper semisphere ("..." operator before "dataitem") and
// changing its "z" attribute into negative vales:
var data = [
dataitem,
{...dataitem, z: c.map(v => -v)}
];
return {data:data, layout:layout};
}
////////////////////
// Example usage:
window.onload = function () {
var sphere = getSphereData("Sphere", 600,600, 0.3, 'rgb(211,211,211)');
Plotly.newPlot('myDiv', sphere.data, sphere.layout);
}
</script>
<div id="myDiv" name="myDiv"></div>
</body>
</html>
我正在尝试用 plotly.js 绘制一个简单的球体。然而,当使用 mesh3d 选项时,球体的图看起来非常粗糙和不精致。任何有关如何平滑它的建议将不胜感激。
a = [];
b = [];
c = [];
phiArr = [];
thetaArr = [];
function makeInterval(startValue, stopValue, numPoints) {
var arr = [];
var step = (stopValue - startValue) / (numPoints - 1);
for (var i = 0; i < numPoints; i++) {
arr.push(startValue + (step * i));
}
return arr;
}
phiArr = makeInterval(0, Math.PI, 20);
thetaArr = makeInterval(0, 2*Math.PI, 20);
for (i=0; i<thetaArr.length; i++){
for (j=0; j<phiArr.length; j++){
a.push(Math.cos(thetaArr[i]) * Math.sin(phiArr[j]));
b.push(Math.sin(thetaArr[i]) * Math.sin(phiArr[j]));
c.push(Math.cos(phiArr[j]));
}
}
var data = [{
opacity: 0.2,
color: 'rgb(211,211,211)',
type: 'mesh3d',
x: a,
y: b,
z: c,
}];
var layout = {
title: 'My Sphere',
autosize: false,
width: 600,
height: 600,
margin: {
l: 65,
r: 50,
b: 65,
t: 90,
}
};
Plotly.newPlot('myDiv', data, layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>
最简单的解决方案是绘制两个半球:
a = [];
b = [];
c = [];
phiArr = [];
thetaArr = [];
function makeInterval(startValue, stopValue, numPoints) {
var arr = [];
var step = (stopValue - startValue) / (numPoints - 1);
for (var i = 0; i < numPoints; i++) {
arr.push(startValue + (step * i));
}
return arr;
}
////////////////
// EDIT 1: calculate only upper half of the sphere
phiArr = makeInterval(0, Math.PI/2, 20);
///////////////
thetaArr = makeInterval(0, 2*Math.PI, 20);
for (i=0; i<thetaArr.length; i++){
for (j=0; j<phiArr.length; j++){
a.push(Math.cos(thetaArr[i]) * Math.sin(phiArr[j]));
b.push(Math.sin(thetaArr[i]) * Math.sin(phiArr[j]));
c.push(Math.cos(phiArr[j]));
}
}
const dataitem = {
opacity: 0.2,
color: 'rgb(211,211,211)',
type: 'mesh3d',
x: a,
y: b,
z: c,
}
//////////////////////
// EDIT 2: obtain the second half of the sphere by duplicating
// the upper semisphere ("..." operator before "dataitem") and
// changing its "z" attribute into negative vales:
var data = [
dataitem,
{...dataitem, z: c.map(v => -v)}
];
//////////////////////
var layout = {
title: 'My Sphere',
autosize: false,
width: 600,
height: 600,
margin: {
l: 65,
r: 50,
b: 65,
t: 90,
}
};
Plotly.newPlot('myDiv', data, layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>
来自@Josef Wittmann 的重要来源,这是一个可以复制到您的代码中的函数:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
</head>
<body>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script>
/////////////////////
function getSphereData(name, width, height, color, opacity) {
var layout = {
title: name,
autosize: false,
width: width,
height: height,
margin: {
l: 65,
r: 50,
b: 65,
t: 90,
}
};
a = [];
b = [];
c = [];
var phiArr = [];
var thetaArr = [];
var numPoints = 20;
var startValue = 0;
var stopValuePhi = Math.PI/2;
var stopValueTheta = 2*Math.PI;
var stepPhi = stopValuePhi / (numPoints - 1);
var stepTheta = stopValueTheta / (numPoints - 1);
for (var i = 0; i < numPoints; i++) {
phiArr.push(stepPhi * i);
thetaArr.push(stepTheta * i);
}
for (i=0; i<thetaArr.length; i++){
for (j=0; j<phiArr.length; j++){
a.push(Math.cos(thetaArr[i]) * Math.sin(phiArr[j]));
b.push(Math.sin(thetaArr[i]) * Math.sin(phiArr[j]));
c.push(Math.cos(phiArr[j]));
}
}
const dataitem = {
opacity: opacity,
color: 'rgb(211,211,211)',
type: 'mesh3d',
x: a,
y: b,
z: c,
}
// Obtain the second half of the sphere by
// duplicating the upper semisphere ("..." operator before "dataitem") and
// changing its "z" attribute into negative vales:
var data = [
dataitem,
{...dataitem, z: c.map(v => -v)}
];
return {data:data, layout:layout};
}
////////////////////
// Example usage:
window.onload = function () {
var sphere = getSphereData("Sphere", 600,600, 0.3, 'rgb(211,211,211)');
Plotly.newPlot('myDiv', sphere.data, sphere.layout);
}
</script>
<div id="myDiv" name="myDiv"></div>
</body>
</html>