为什么这组F在这个轨迹旋转
Why is this set of F rotating in this locus
在这段代码中,我无法理解为什么旋转不是在圆形轨迹中。这可能是这背后的基本逻辑,但我不明白为什么这个轨迹如此随机。
我在轨道运动中旋转相机,但它没有跟随它。
据我所知,我创建了一个轨道运动相机,它的逆矩阵是视图矩阵。所以,视图矩阵将改变世界 space 为此 result.Is 我的思维过程有什么错误吗?
"use strict";
const vertexShader = `#version 300 es
in vec4 a_position;
in vec4 a_color;
out vec4 v_color;
uniform mat4 u_matrix;
void main(){
gl_Position = u_matrix*a_position;
v_color = a_color;
}
`;
const fragShader = `#version 300 es
precision highp float;
in vec4 v_color;
out vec4 frag_color;
void main(){
frag_color = v_color;
}
`;
var cameraAngleDegree = 0;
var cameraAngle = 0;
const radius = 100;
var increment = 1;
var numFs = 5;
function main() {
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl2");
if (!gl) {
return;
}
requestAnimationFrame(function() {
init(gl);
});
}
function init(gl) {
const program = webglUtils.createProgramFromSources(gl, [vertexShader, fragShader]);
const apositionLoc = gl.getAttribLocation(program, 'a_position');
const acolorLoc = gl.getAttribLocation(program, 'a_color');
const umatrixLoc = gl.getUniformLocation(program, 'u_matrix');
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
let positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
setGeometry(gl);
gl.enableVertexAttribArray(apositionLoc);
let size = 3;
let type = gl.FLOAT;
let normalize = false;
let stride = 0;
let offset = 0;
gl.vertexAttribPointer(apositionLoc, size, type, normalize, stride, offset);
let colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
setColor(gl);
gl.enableVertexAttribArray(acolorLoc);
size = 3;
type = gl.UNSIGNED_BYTE;
normalize = true;
stride = 0;
offset = 0;
gl.vertexAttribPointer(acolorLoc, size, type, normalize, stride, offset);
let fov = degreeToRadian(60);
cameraAngle = degreeToRadian(cameraAngleDegree);
function degreeToRadian(deg) {
return deg * Math.PI / 180;
}
function radToDegree(rad) {
return rad * (180) / Math.PI;
}
drawScene();
// webglLessonsUI.setupSlider("#cameraAngle", { value: radToDegree(cameraAngle), slide: updateCameraAngle, min: -360, max: 360 });
// function updateCameraAngle(event, ui) {
// cameraAngle = degreeToRadian(ui.value);
// drawScene();
// }
function drawScene() {
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.CULL_FACE);
gl.enable(gl.DEPTH_TEST);
gl.useProgram(program);
let aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
let projection = m4.perspective(fov, aspect, 1, 1000);
const fPosition = [radius, 0, 0];
cameraAngleDegree += increment;
cameraAngle =degreeToRadian(cameraAngleDegree);
let camera = m4.yRotation(cameraAngle);
camera = m4.translate(camera, 0, 100, 300);
let cameraPosition = [camera[12], camera[13], camera[14]];
// let up = [0, 1, 0];
// camera = m4.lookAt(cameraPosition, fPosition, up);
let viewMatrix = m4.inverse(camera);
let viewProjection = m4.multiply(projection, viewMatrix);
for (var ii = 0; ii < numFs; ++ii) {
var angle = ii * Math.PI * 2 / numFs;
var x = Math.cos(angle) * radius;
var z = Math.sin(angle) * radius;
var matrix = m4.translate(viewProjection, x, 0, z);
// Set the matrix.
gl.uniformMatrix4fv(umatrixLoc, false, matrix);
// Draw the geometry.
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 16 * 6;
gl.drawArrays(primitiveType, offset, count);
}
// gl.uniformMatrix4fv(umatrixLoc, false, viewProjection);
// var primitives = gl.TRIANGLES;
// var count = 16 * 6;
// var offset = 0;
// gl.drawArrays(primitives, offset, count);
// }
requestAnimationFrame(function() {
init(gl)
});
}
}
function setGeometry(gl) {
let positions = new Float32Array([
0, 0, 0,
0, 150, 0,
30, 0, 0,
0, 150, 0,
30, 150, 0,
30, 0, 0,
// top rung front
30, 0, 0,
30, 30, 0,
100, 0, 0,
30, 30, 0,
100, 30, 0,
100, 0, 0,
// middle rung front
30, 60, 0,
30, 90, 0,
67, 60, 0,
30, 90, 0,
67, 90, 0,
67, 60, 0,
// left column back
0, 0, 30,
30, 0, 30,
0, 150, 30,
0, 150, 30,
30, 0, 30,
30, 150, 30,
// top rung back
30, 0, 30,
100, 0, 30,
30, 30, 30,
30, 30, 30,
100, 0, 30,
100, 30, 30,
// middle rung back
30, 60, 30,
67, 60, 30,
30, 90, 30,
30, 90, 30,
67, 60, 30,
67, 90, 30,
// top
0, 0, 0,
100, 0, 0,
100, 0, 30,
0, 0, 0,
100, 0, 30,
0, 0, 30,
// top rung right
100, 0, 0,
100, 30, 0,
100, 30, 30,
100, 0, 0,
100, 30, 30,
100, 0, 30,
// under top rung
30, 30, 0,
30, 30, 30,
100, 30, 30,
30, 30, 0,
100, 30, 30,
100, 30, 0,
// between top rung and middle
30, 30, 0,
30, 60, 30,
30, 30, 30,
30, 30, 0,
30, 60, 0,
30, 60, 30,
// top of middle rung
30, 60, 0,
67, 60, 30,
30, 60, 30,
30, 60, 0,
67, 60, 0,
67, 60, 30,
// right of middle rung
67, 60, 0,
67, 90, 30,
67, 60, 30,
67, 60, 0,
67, 90, 0,
67, 90, 30,
// bottom of middle rung.
30, 90, 0,
30, 90, 30,
67, 90, 30,
30, 90, 0,
67, 90, 30,
67, 90, 0,
// right of bottom
30, 90, 0,
30, 150, 30,
30, 90, 30,
30, 90, 0,
30, 150, 0,
30, 150, 30,
// bottom
0, 150, 0,
0, 150, 30,
30, 150, 30,
0, 150, 0,
30, 150, 30,
30, 150, 0,
// left side
0, 0, 0,
0, 0, 30,
0, 150, 30,
0, 0, 0,
0, 150, 30,
0, 150, 0,
]);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW)
}
function setColor(gl) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Uint8Array([
// left column front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// top rung front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// middle rung front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// left column back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// top rung back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// middle rung back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// top
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
// top rung right
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
// under top rung
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
// between top rung and middle
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
// top of middle rung
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
// right of middle rung
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
// bottom of middle rung.
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
// right of bottom
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
// bottom
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
// left side
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
]),
gl.STATIC_DRAW);
}
main();
<!DOCTYPE html>
<html>
<head>
<title>Traingle Webgl 2</title>
<style type="text/css">
@import url("https://webglfundamentals.org/webgl/resources/webgl-tutorials.css");
body {
margin: 0;
}
button {
position: absolute;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="uiContainer">
<div id="ui">
<div id="cameraAngle"></div>
</div>
</div>
<!--
for most samples webgl-utils only provides shader compiling/linking and
canvas resizing because why clutter the examples with code that's the same in every sample.
See https://webglfundamentals.org/webgl/lessons/webgl-boilerplate.html
and https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
for webgl-utils, m3, m4, and webgl-lessons-ui.
-->
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-lessons-ui.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
<script src="https://greggman.github.io/webgl-helpers/webgl-gl-error-check.js"></script>
<script type="text/javascript" src="js/lookat.js"></script>
<!-- <script type="text/javascript" src="js/camera.js"></script> -->
</body>
</html>
如果我理解你的问题,你看到的问题是看起来相机离 Fs 越来越近和越来越远
问题是 Fs 的顶点数据是这样构建的,所以左上角前角位于 0,0,0,从那里他们去 +X 100 个单位(所以 100 个单位宽),+Y 150 个单位(所以 100 个单位高),+Z 30 个单位所以 30 个单位深
那么,当您围绕 100 个单位的圆绘制它们时,它们的原点就是您要定位的部分,您会得到这个
图像是自上而下的,所以 Fs 只是一个矩形。绿色圆圈是每个 F 的局部原点,即局部 0,0,0。 F 的其他顶点相对于该局部原点,因此它们在一侧更靠近外圆(相机的轨道),而在另一侧更远
您可以通过将 Fs 在 X 方向移动 -50 和在 Z 方向移动 -15 来修复它。换句话说
var angle = ii * Math.PI * 2 / numFs;
var x = Math.cos(angle) * radius - 50;
var z = Math.sin(angle) * radius - 15;
这给了你这种情况
每个F的本地原点不再在圆上。
您也可以通过将 F 顶点数据居中来修复它,遍历所有顶点并从 X 中减去 50,从 Z 中减去 15。这会给您带来这种情况
现在每个F的原点都居中,局部原点在圆上。
另一种解决方法是计算 F 组的范围,计算范围的中心,将相机轨道的中心移动到那里,这就是这种情况
在这段代码中,我无法理解为什么旋转不是在圆形轨迹中。这可能是这背后的基本逻辑,但我不明白为什么这个轨迹如此随机。
我在轨道运动中旋转相机,但它没有跟随它。
据我所知,我创建了一个轨道运动相机,它的逆矩阵是视图矩阵。所以,视图矩阵将改变世界 space 为此 result.Is 我的思维过程有什么错误吗?
"use strict";
const vertexShader = `#version 300 es
in vec4 a_position;
in vec4 a_color;
out vec4 v_color;
uniform mat4 u_matrix;
void main(){
gl_Position = u_matrix*a_position;
v_color = a_color;
}
`;
const fragShader = `#version 300 es
precision highp float;
in vec4 v_color;
out vec4 frag_color;
void main(){
frag_color = v_color;
}
`;
var cameraAngleDegree = 0;
var cameraAngle = 0;
const radius = 100;
var increment = 1;
var numFs = 5;
function main() {
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl2");
if (!gl) {
return;
}
requestAnimationFrame(function() {
init(gl);
});
}
function init(gl) {
const program = webglUtils.createProgramFromSources(gl, [vertexShader, fragShader]);
const apositionLoc = gl.getAttribLocation(program, 'a_position');
const acolorLoc = gl.getAttribLocation(program, 'a_color');
const umatrixLoc = gl.getUniformLocation(program, 'u_matrix');
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
let positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
setGeometry(gl);
gl.enableVertexAttribArray(apositionLoc);
let size = 3;
let type = gl.FLOAT;
let normalize = false;
let stride = 0;
let offset = 0;
gl.vertexAttribPointer(apositionLoc, size, type, normalize, stride, offset);
let colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
setColor(gl);
gl.enableVertexAttribArray(acolorLoc);
size = 3;
type = gl.UNSIGNED_BYTE;
normalize = true;
stride = 0;
offset = 0;
gl.vertexAttribPointer(acolorLoc, size, type, normalize, stride, offset);
let fov = degreeToRadian(60);
cameraAngle = degreeToRadian(cameraAngleDegree);
function degreeToRadian(deg) {
return deg * Math.PI / 180;
}
function radToDegree(rad) {
return rad * (180) / Math.PI;
}
drawScene();
// webglLessonsUI.setupSlider("#cameraAngle", { value: radToDegree(cameraAngle), slide: updateCameraAngle, min: -360, max: 360 });
// function updateCameraAngle(event, ui) {
// cameraAngle = degreeToRadian(ui.value);
// drawScene();
// }
function drawScene() {
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.CULL_FACE);
gl.enable(gl.DEPTH_TEST);
gl.useProgram(program);
let aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
let projection = m4.perspective(fov, aspect, 1, 1000);
const fPosition = [radius, 0, 0];
cameraAngleDegree += increment;
cameraAngle =degreeToRadian(cameraAngleDegree);
let camera = m4.yRotation(cameraAngle);
camera = m4.translate(camera, 0, 100, 300);
let cameraPosition = [camera[12], camera[13], camera[14]];
// let up = [0, 1, 0];
// camera = m4.lookAt(cameraPosition, fPosition, up);
let viewMatrix = m4.inverse(camera);
let viewProjection = m4.multiply(projection, viewMatrix);
for (var ii = 0; ii < numFs; ++ii) {
var angle = ii * Math.PI * 2 / numFs;
var x = Math.cos(angle) * radius;
var z = Math.sin(angle) * radius;
var matrix = m4.translate(viewProjection, x, 0, z);
// Set the matrix.
gl.uniformMatrix4fv(umatrixLoc, false, matrix);
// Draw the geometry.
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 16 * 6;
gl.drawArrays(primitiveType, offset, count);
}
// gl.uniformMatrix4fv(umatrixLoc, false, viewProjection);
// var primitives = gl.TRIANGLES;
// var count = 16 * 6;
// var offset = 0;
// gl.drawArrays(primitives, offset, count);
// }
requestAnimationFrame(function() {
init(gl)
});
}
}
function setGeometry(gl) {
let positions = new Float32Array([
0, 0, 0,
0, 150, 0,
30, 0, 0,
0, 150, 0,
30, 150, 0,
30, 0, 0,
// top rung front
30, 0, 0,
30, 30, 0,
100, 0, 0,
30, 30, 0,
100, 30, 0,
100, 0, 0,
// middle rung front
30, 60, 0,
30, 90, 0,
67, 60, 0,
30, 90, 0,
67, 90, 0,
67, 60, 0,
// left column back
0, 0, 30,
30, 0, 30,
0, 150, 30,
0, 150, 30,
30, 0, 30,
30, 150, 30,
// top rung back
30, 0, 30,
100, 0, 30,
30, 30, 30,
30, 30, 30,
100, 0, 30,
100, 30, 30,
// middle rung back
30, 60, 30,
67, 60, 30,
30, 90, 30,
30, 90, 30,
67, 60, 30,
67, 90, 30,
// top
0, 0, 0,
100, 0, 0,
100, 0, 30,
0, 0, 0,
100, 0, 30,
0, 0, 30,
// top rung right
100, 0, 0,
100, 30, 0,
100, 30, 30,
100, 0, 0,
100, 30, 30,
100, 0, 30,
// under top rung
30, 30, 0,
30, 30, 30,
100, 30, 30,
30, 30, 0,
100, 30, 30,
100, 30, 0,
// between top rung and middle
30, 30, 0,
30, 60, 30,
30, 30, 30,
30, 30, 0,
30, 60, 0,
30, 60, 30,
// top of middle rung
30, 60, 0,
67, 60, 30,
30, 60, 30,
30, 60, 0,
67, 60, 0,
67, 60, 30,
// right of middle rung
67, 60, 0,
67, 90, 30,
67, 60, 30,
67, 60, 0,
67, 90, 0,
67, 90, 30,
// bottom of middle rung.
30, 90, 0,
30, 90, 30,
67, 90, 30,
30, 90, 0,
67, 90, 30,
67, 90, 0,
// right of bottom
30, 90, 0,
30, 150, 30,
30, 90, 30,
30, 90, 0,
30, 150, 0,
30, 150, 30,
// bottom
0, 150, 0,
0, 150, 30,
30, 150, 30,
0, 150, 0,
30, 150, 30,
30, 150, 0,
// left side
0, 0, 0,
0, 0, 30,
0, 150, 30,
0, 0, 0,
0, 150, 30,
0, 150, 0,
]);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW)
}
function setColor(gl) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Uint8Array([
// left column front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// top rung front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// middle rung front
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
200, 70, 120,
// left column back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// top rung back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// middle rung back
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
80, 70, 200,
// top
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
70, 200, 210,
// top rung right
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
200, 200, 70,
// under top rung
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
210, 100, 70,
// between top rung and middle
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
210, 160, 70,
// top of middle rung
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
70, 180, 210,
// right of middle rung
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
100, 70, 210,
// bottom of middle rung.
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
76, 210, 100,
// right of bottom
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
140, 210, 80,
// bottom
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
90, 130, 110,
// left side
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
160, 160, 220,
]),
gl.STATIC_DRAW);
}
main();
<!DOCTYPE html>
<html>
<head>
<title>Traingle Webgl 2</title>
<style type="text/css">
@import url("https://webglfundamentals.org/webgl/resources/webgl-tutorials.css");
body {
margin: 0;
}
button {
position: absolute;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="uiContainer">
<div id="ui">
<div id="cameraAngle"></div>
</div>
</div>
<!--
for most samples webgl-utils only provides shader compiling/linking and
canvas resizing because why clutter the examples with code that's the same in every sample.
See https://webglfundamentals.org/webgl/lessons/webgl-boilerplate.html
and https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
for webgl-utils, m3, m4, and webgl-lessons-ui.
-->
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-lessons-ui.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
<script src="https://greggman.github.io/webgl-helpers/webgl-gl-error-check.js"></script>
<script type="text/javascript" src="js/lookat.js"></script>
<!-- <script type="text/javascript" src="js/camera.js"></script> -->
</body>
</html>
如果我理解你的问题,你看到的问题是看起来相机离 Fs 越来越近和越来越远
问题是 Fs 的顶点数据是这样构建的,所以左上角前角位于 0,0,0,从那里他们去 +X 100 个单位(所以 100 个单位宽),+Y 150 个单位(所以 100 个单位高),+Z 30 个单位所以 30 个单位深
那么,当您围绕 100 个单位的圆绘制它们时,它们的原点就是您要定位的部分,您会得到这个
图像是自上而下的,所以 Fs 只是一个矩形。绿色圆圈是每个 F 的局部原点,即局部 0,0,0。 F 的其他顶点相对于该局部原点,因此它们在一侧更靠近外圆(相机的轨道),而在另一侧更远
您可以通过将 Fs 在 X 方向移动 -50 和在 Z 方向移动 -15 来修复它。换句话说
var angle = ii * Math.PI * 2 / numFs;
var x = Math.cos(angle) * radius - 50;
var z = Math.sin(angle) * radius - 15;
这给了你这种情况
每个F的本地原点不再在圆上。
您也可以通过将 F 顶点数据居中来修复它,遍历所有顶点并从 X 中减去 50,从 Z 中减去 15。这会给您带来这种情况
现在每个F的原点都居中,局部原点在圆上。
另一种解决方法是计算 F 组的范围,计算范围的中心,将相机轨道的中心移动到那里,这就是这种情况