检测光线与立方体相交的问题

huangapple go评论66阅读模式
英文:

Problem on checking Ray and Cube intersection

问题

以下是您要翻译的部分:

I am stuck right now with my RubiksCube Project.

What I want to achieve: On left-click checking if a single Mini-Cubie was clicked or not.
(The Cube might be rotated when clicked)

The Code of the other Rubiks Cube classes works correctly.
We need to calculate the functions on our own with math formulas.

Current Problems:

  • Clicking on Edges is not being detected
  • After the rotation clicking at a point sometimes leads to: Wrong layer being marked as clicked or no layer being marked as clicked

My general idea was to save the coords of every Layer's 4 Corner Points, updating their position when rotated and checking the Intersection of the Ray with help of these locations

void MergedCube::Render(float aspectRatio)
{

	m_viewProject = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f) *
		            glm::lookAt(glm::vec3(0.0f, 0.0f, -9.0f), 
                                glm::vec3(0.0f), 
                                glm::vec3(0.0f, 1.0f, 0.0f)) *
		            glm::mat4_cast(m_orientationQuaternion);

		compound = glm::translate(m_viewProject, (glm::vec3(1, 1, 1) - 1.0f));

		m_cubieRenderer.Render(compound);
			

    // Calling LayerCalculation() for every Layer with direction -1 or 1


}

This method is supposed to calculate my helper vector, the 2 direction vectors
and the normalization vector of every Layer

void MergedCube::LayerCalculation(std::vector<glm::vec3>& points, int normDirection) {

	while (points.size() > 4) {
		points.erase(points.end()-1);
	}

	glm::vec3 middlePoint = (points[0] + points[2]) / 2.0f;
	glm::vec3 firstPoint = (points[0] + points[1]) / 2.0f;
	glm::vec3 secondPoint = (points[0] + points[3]) / 2.0f;

	glm::vec3 vecA = glm::normalize(firstPoint - middlePoint);
	glm::vec3 vecB = glm::normalize(secondPoint - middlePoint);
	
	glm::vec3 normalVector = glm::cross(vecA, vecB) * glm::vec3(direction);

	points.push_back(middlePoint);
	points.push_back(vecA);
	points.push.add(vecB);
	points.push_back(normalVector);	
	
}

Now the RayAndCubeIntersection method.

bool MergedCube::RayAndCubeIntersection(glm::vec3 startingPoint, glm::vec3 direction, 
                                        std::vector<glm::vec3> Pts) {

	glm::vec3 helperVec = pts[4];
	glm::vec3 normVec = pts[7];
	glm::vec3 directionVecA = pts[5];
	glm::vec3 directionVecB = pts[6];

if (glm::dot(rayDirection, normVec) < 0) {

		float res = normVec[0] * helperVec[0] + normVec[1] * helperVec[1] + normVec[2] * helperVec[2];
		float directionMultiplier = (res - normVec[0] * rayStartingPoint[0] - normVec[1] * rayStartingPoint[1] - normVec[2] * rayStartingPoint[2]) /
			                           (normVec[0] * rayDirection[0] + normVec[1] * rayDirection[1] + normVec[2] * rayDirection[2]);
		glm::vec3 crosspoint = rayStartingPoint + rayDirection * glm::vec3(directionMultiplier);

		if (glm::dot(crosspoint - helperVec, normVec) == 0) {

			float x = glm::dot(directionVecA, crosspoint - helperVec);
			float y = glm::dot(directionVecB, crosspoint - helperVec);

			if (x > -0.5001 && x < 0.5001) {
				if (y > -0.5001 && y < 0.5001) {
					return true;
				}
			}	
		}
	}
	return false;
}

Edit: I changed my Code quite a bit, now clicking the cube is being detected in many cases.

英文:

I am stuck right now with my RubiksCube Project.

What I want to achieve: On left-click checking if a single Mini-Cubie was clicked or not.
(The Cube might be rotated when clicked)

The Code of the other Rubiks Cube classes works correctly.
We need to calculate the functions on our own with math formulas.

Current Problems:

  • Clicking on Edges is not being detected
  • After the rotation clicking at a point sometimes leads to: Wrong layer being marked as clicked or no layer being marked as clicked

My general idea was to safe the coords of every Layer´s 4 Corner Points, updating their position when rotated and checking the Intersection of the Ray with help of these locations

void MergedCube::Render(float aspectRatio)
{

	m_viewProject = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f) *
		            glm::lookAt(glm::vec3(0.0f, 0.0f, -9.0f), 
                                glm::vec3(0.0f), 
                                glm::vec3(0.0f, 1.0f, 0.0f)) *
		            glm::mat4_cast(m_orientationQuaternion);

		compound = glm::translate(m_viewProject, (glm::vec3(1, 1, 1) - 1.0f));

		m_cubieRenderer.Render(compound);
			

    // Calling LayerCalculation() for every Layer with direction -1 or 1


}

This method is supposed to calculate my helper vector, the 2 direction vectors
and the normalisation vector of every Layer

void MergedCube::LayerCalculation(std::vector&lt;glm::vec3&gt;&amp; points, int normDirection) {

	while (points.size() &gt; 4) {
		points.erase(points.end()-1);
	}

	glm::vec3 middlePoint = (points[0] + points[2]) / 2.0f;
	glm::vec3 firstPoint = (points[0] + points[1]) / 2.0f;
	glm::vec3 secondPoint = (points[0] + points[3]) / 2.0f;

	glm::vec3 vecA = glm::normalize(firstPoint - middlePoint);
	glm::vec3 vecB = glm::normalize(secondPoint - middlePoint);
	
	glm::vec3 normalVector = glm::cross(vecA,vecB) * glm::vec3(direction);

	points.push_back(middlePoint);
	points.push_back(vecA);
	points.push_back(vecB);
	points.push_back(normalVector);	
	
}

Now the RayAndCubeIntersection method.

bool MergedCube::RayAndCubeIntersection(glm::vec3 startingPoint, glm::vec3 direction, 
                                        std::vector&lt;glm::vec3&gt; Pts) {

	glm::vec3 helperVec = pts[4];
	glm::vec3 normVec = pts[7];
	glm::vec3 directionVecA = pts[5];
	glm::vec3 directionVecB = pts[6];

if (glm::dot(rayDirection, normVec) &lt; 0) {

		float res = normVec[0] * helperVec[0] + normVec[1] * helperVec[1] + normVec[2] * helperVec[2];
		float directionMultiplikator = (res - normVec[0] * rayStartingPoint[0] - normVec[1] * rayStartingPoint[1] - normVec[2] * rayStartingPoint[2]) /
			                           (normVec[0] * rayDirection[0] + normVec[1] * rayDirection[1] + normVec[2] * rayDirection[2]);
		glm::vec3 crosspoint = rayStartingPoint + rayDirection * glm::vec3(directionMultiplikator);

		if (glm::dot(crosspoint - helperVec,normVec) == 0) {

			float x = glm::dot(directionVecA,crosspoint - helperVec);
			float y = glm::dot(directionVecB, crosspoint - helperVec);

			if (x &gt; -0.5001 &amp;&amp; x &lt; 0.5001) {
				if (y &gt; -0.5001 &amp;&amp; y &lt; 0.5001) {
					return true;
				}
			}	
		}
	}
	return false;
}

Edit: I changed my Code quite a bit, now clicking the cube is being detected in many cases.

答案1

得分: 0

以下是您要翻译的内容:

原文:
Well I guess it is time to answer my own question.
The actual problem of my code was checking glm::dot(crosspoint - helperVec,normVec) == 0.
But instead I am supposed to check for glm::abs(glm::dot(crosspoint - helperVec,normVec)) &lt; EPSILON with a really small EPSILON value.

Note to myself: When using floats never check against 0

翻译:
好吧,我想是时候回答自己的问题了。
我的代码实际问题是检查 glm::dot(crosspoint - helperVec,normVec) == 0
而实际上,我应该检查 glm::abs(glm::dot(crosspoint - helperVec,normVec)) &lt; EPSILON,EPSILON 值应该非常小。

自己提醒:在使用浮点数时,永远不要检查是否等于 0。

英文:

Well I guess it is time to answer my own question.
The actual problem of my code was checking glm::dot(crosspoint - helperVec,normVec) == 0 .
But instead I am supposed to check for glm::abs(glm::dot(crosspoint - helperVec,normVec)) &lt; EPSILON with a really small EPSILON value.

Note to myself: When using floats never check against 0

huangapple
  • 本文由 发表于 2023年3月31日 04:34:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75892776.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定