signed distance between plane and point - math

I cannot find a consistent method for finding the signed distance between a point and a plane. How can I calculate this given a plane defined as a point and a normal?
struct Plane
{
Vec3 point;
Vec3 normal;
}

You're making things much too complicated. If your normal is normalized, you can just do this:
float dist = dotProduct(p.normal, (vectorSubtract(point, p.point)));

Related

How to rotate an object so that it is directed exactly to the coordinates of another object?

There is an object. At zero coordinates, the object looks forward, you can say a line comes out of its coordinates. This is the direction of the object. You can imagine with a car. In front of the car is where it looks. Its coordinates in x, y, z are known, as well as its slope in x, y, z in radians or degrees.
The coordinates of the second object are known.
How can you find out how many degrees or radians you need to rotate the car on all axes so that it is directed exactly to the coordinate of the second object?
The object can be rotated along all axes as shown in the figure. The values can be in degrees or radians.
I tried to find a solution, but I found only ready-made functions for this in the Unity, Unreal Engine engines
To find out how many degrees or radians you need to rotate an object along all axes (pitch, yaw, and roll), you can use a Delta Find function. This function takes two rotations as input: the current rotation of the object and the target rotation. It returns the rotation that will make the object face the target rotation.
// Assume that Object1 has a known starting rotation and you want to rotate it to a specific target rotation
FRotator StartingRotation = Object1->GetActorRotation();
FRotator TargetRotation = ...; // Set the target rotation to the desired value
// Calculate the rotation needed to make Object1 face the target rotation
FRotator DeltaRotation = FindDeltaRotation(StartingRotation, TargetRotation);
// Add the calculated delta rotation to the starting rotation to get the final rotation
FRotator FinalRotation = StartingRotation + DeltaRotation;
// Set the rotation of Object1 to the final rotation
Object1->SetActorRotation(FinalRotation);
This will rotate Object1 so that it is facing the target rotation. Note that the Find Delta Rotation function will rotate the object around all axes (pitch, yaw, and roll) as needed to achieve the desired orientation.
All FindDeltaRotation is:
FRotator FindDeltaRotation(const FRotator& A, const FRotator& B)
{
return B - A;
}

return local 2D coords of a 3D point on a 2D plane in space?

As the title suggests, I don't know where to start on this problem:
I have a a 2D plane defined by it's origin point in global coordinates(x,y,z) and its axis endpoints as well, but I don't know how to return the local coordinates of a point on the plane
I found this solution but it gave false results:
// given information
`Vector3 origin;
Vector3 planeXDir;
Vector3 planeYDir;
Vector3 pointOnPlane;
Vector3 v = pointOnPlane - origin;
Vector2 positionInPlane = new Vector2(Vector3.Dot(planeXDir, v), Vector3.Dot(planeYDir, v));`
I don't know where I went wrong, maybe a misconception of planeXDir and planeYDir? I'd be happy if someone could explain or give me an easier solution to implement.
That code is correct, so there're misconceptions or mistakes somewhere.
Check that planeXDir & planeDir are orthogonal, and unit (or if not unit that you really want a scaling difference between unit lengths in 3D vs the plane).

How to rotate a Vector3 using Vector2?

I want to simulate particles driven by wind on a three.js globe. The data I have is a Vector3 for the position of a particle and a Vector2 indicating wind speed and direction, think North/East. How do I get the new Vector3?
I've consulted numerous examples and read the documentation and believe the solution involves quaternions, but the axis of rotation is not given. Also, there are thousands of particles, it should be fast, however real-time is not required.
The radius of the sphere is 1.
I would recommend you have a look at the Spherical class provided by three.js. Instead of cartesian coordinates (x,y,z), a point is represented in terms of a spherical coordinate-system (θ (theta), φ (phi), r).
The value of theta is the longitude and phi is the latitude for your globe (r - sphereRadius would be the height above the surface). Your wind-vectors can then be interpreted as changes to these two values. So what I would try is basically this:
// a) convert particle-location to spherical
const sphericalPosition = new THREE.Spherical()
.setFromVector3(particle.position);
// b) update theta/phi (note that windSpeed is assumed to
// be given in radians/time, but for a sphere of size 1 that
// shouldn't make a difference)
sphericalPosition.theta += windSpeed.x; // east-direction
sphericalPosition.phi += windSpeed.y; // north-direction
// c) write back to particle-position
particle.position.setFromSpherical(sphericalPosition);
Performance wise this shouldn't be a problem at all (maybe don't create a new Spherical-instance for every particle like I did above). The conversions involve a bit of trigonometry, but we're talking just thousands of points, not millions.
Hope that helps!
If you just want to rotate a vector based on an angle, just perform a simple rotation of values on the specified plane yourself using trig as per this page eg for a rotation on the xz plane:
var x = cos(theta)*vec_to_rotate.x - sin(theta)*vec_to_rotate.z;
var z = sin(theta)*vec_to_rotate.x + cos(theta)*vec_to_rotate.z;
rotated_vector = new THREE.Vector3(x,vec_to_rotate.y,z);
But to move particles with wind, you're not really rotating a vector, you should be adding a velocity vector, and it 'rotates' its own heading based on a combination of initial velocity, inertia, air friction, and additional competing forces a la:
init(){
position = new THREE.Vector(0,0,0);
velocity = new THREE.Vector3(1,0,0);
wind_vector = new THREE.Vector3(0,0,1);
}
update(){
velocity.add(wind_vector);
position.add(velocity);
velocity.multiplyScalar(.95);
}
This model is truer to how wind will influence a particle. This particle will start off heading along the x axis, and then 'turn' eventually to go in the direction of the wind, without any rotation of vectors. It has a mass, and a velocity in a direction, a force is acting on it, it turns.
You can see that because the whole velocity is subject to friction (the multscalar), our initial velocity diminishes as the wind vector accumulates, which causes a turn without performing any rotations. Thought i'd throw this out just in case you're unfamiliar with working with particle systems and maybe were just thinking about it wrong.

Normals of height map dont work

Iam trying to implement normals for my height map but they dont seems to work.
Look at these:
Note that the pattern occurs along the edges. Why?
Vertices are shared (indexing) and normals are average for vertex from all triangles that vertex is part of.
Algorithm for normals looks like that:
float size=Size;
int WGidY=int(gl_WorkGroupID.y);
int WGidX=int(gl_WorkGroupID.x);
vec4 tempVertices[3];
tempVertices[0]=imageLoad(HeightMap, ivec2(WGidX, WGidY));
tempVertices[1]=imageLoad(HeightMap, ivec2(WGidX, WGidY+1));
tempVertices[2]=imageLoad(HeightMap, ivec2(WGidX+1, WGidY));
vec4 LoadedNormal=imageLoad(NormalMap, ivec2(WGidX, WGidY));
vec4 Normal=vec4(0.0f);
Normal.xyz=cross((tempVertices[0].xyz-tempVertices[1].xyz), (tempVertices[0].xyz-tempVertices[2].xyz));
Normal.w=1;
imageStore(NormalMap, ivec2(WGidX,WGidY), Normal+LoadedNormal);
No need to do averaging like that. You can compute it directly in one step as follows:
vec3 v[4] = {
imageLoad(HeightMap, ivec2(WGidX-1, WGidY)).xyz,
imageLoad(HeightMap, ivec2(WGidX+1, WGidY)).xyz,
imageLoad(HeightMap, ivec2(WGidX, WGidY-1)).xyz,
imageLoad(HeightMap, ivec2(WGidX, WGidY+1)).xyz,
};
vec3 Normal = normalize(cross(v[1] - v[0], v[3] - v[2]));
imageStore(NormalMap, ivec2(WGidX,WGidY), vec4(Normal, 1));
Also you don't even need to store the HeightMap mesh explicitly. Instead you can send the same low-resolution quad to the GPU, tessellate it with a tessellation shader, apply the height map to the generated vertices by sampling from a one-channel texture, and compute the normals on-the-fly as above.
ok guys, I found a problem. This is symptom of "greedy triangulation". The normals inside a triangle are interpolated by barycentric algorithm but the edges are interpolated linearly to prevent color differences between adjacting triangles. Thank you, again, Paul Bourke:
http://paulbourke.net/texture_colour/interpolation/
If you dont have enough triangles dont use Phong Shading (maybe normal mapping?).
After tweaks:
http://prntscr.com/dadrue
http://prntscr.com/dadtum
http://prntscr.com/dadugf

How to determine if sphere is in front of plane

I want to do frustum culling for my engine :)
On this site seems to be nice example how to do this, but there is one thing I don't get:
if ( D3DXPlaneDotCoord( &m_frustum[i], pPosition ) + radius < 0 )
{
// Outside the frustum, reject it!
return FALSE;
}
Is why there is a radius for?
Or maybe what is dependence between dot product and distance from plane?
Cause with my actual knowledge I would calculate it like that:
calculate dot product of plane. And as vectors are normalized dot product is equal to cosinus of angle between vectors. So it can return values between -1 and 1.(Thats why I dont understand why radius is added). And if cos > 0 means that angle is between 0 and 90 degrees. So center point is in front of plane. Then I would use equation for distance of point from plane. And check if that distance is higer than radius of sphere. But this guy have this in that one equation. What magic is behid that?
Ok I see where is my mistake dot procuct is not equal to cos of angle, but cos of angle and length of vector P( describing position of center of sphere). So what exactly is cos*|P| = ?
http://tinypic.com/r/2vxrpkw/5( no rep for images )
Probably answered own question brb( wikipedia ) :)
Yeah exactly. My P is not P desribing point in coordinate system, but It's P - known point of plane. So it's vector between point and know point of plane. Everything seems legit. Thanks for help :P It's nicely explained here: www.songho.ca/math/plane/plane.html
This can be seen as a projection of the pPosition along the plane's normal.
If the length of this projection plus the plane's D component minus the sphere radius is less than zero means the sphere is behind.

Resources