Align Geometry to Plane selecting 3 intersected points - math

I have a few days trying to align the 3D object selecting 3 points intersected on the 3D object.
I have to align the GEOMETRY to the the plane.
I started getting the crossVectors from the 3 points.
First Step i did is to move the first point selected to the 0,0,0 position:
After move, as you can see the points are not updated.
let matrixToApply = new Matrix4().makeTranslation(
-this.aligningPoints[0].x,
-this.aligningPoints[0].y,
-this.aligningPoints[0].z
);
this.mesh.geometry.applyMatrix4(matrixToApply)
After this step, the next is to rotate the first point and the second one, getting the angle between, it's so stupid code, I need some help to get some better solution for tha, like apply quarention on euler. I just need to rotate and match to the plane.
if (crossVectors.x > 0 && crossVectors.y > 0 && crossVectors.z < 0) {
console.log('+ + -');
var rotateX = new THREE.Vector3(0, 0, 100).angleTo(new THREE.Vector3(0, crossVectors.y, crossVectors.z));
this.mesh.geometry.rotateX(rotateX);
} else if (crossVectors.x > 0 && crossVectors.y < 0 && crossVectors.z < 0) {
console.log('+ - -');
var rotateX = new THREE.Vector3(0, 0, -100).angleTo(new THREE.Vector3(0, crossVectors.y, crossVectors.z));
this.mesh.geometry.rotateX(rotateX);
} else if (crossVectors.x > 0 && crossVectors.y < 0 && crossVectors.z > 0) {
console.log(' + - +');
var rotateX = new THREE.Vector3(0, 0, 100).normalize().angleTo(new THREE.Vector3(crossVectors.x, 0, crossVectors.z).normalize());
this.mesh.geometry.rotateY(-rotateX);
} else if (crossVectors.x < 0 && crossVectors.y < 0 && crossVectors.z > 0) {
console.log('- - +');
var rotateX = new THREE.Vector3(0, 0, 100).normalize().angleTo(new THREE.Vector3(0, crossVectors.y, crossVectors.z).normalize());
this.mesh.geometry.rotateX(-rotateX);
} else if (crossVectors.x < 0 && crossVectors.y < 0 && crossVectors.z < 0) {
console.log('- - -');
var rotateX = new THREE.Vector3(0, 0, -100).normalize().angleTo(new THREE.Vector3(0, crossVectors.y, crossVectors.z).normalize());
this.mesh.geometry.rotateX(rotateX);
} else if (crossVectors.x > 0 && crossVectors.y > 0 && crossVectors.z > 0) {
console.log('+ + +');
var rotateX = new THREE.Vector3(0, 0, 100).normalize().angleTo(new THREE.Vector3(0, crossVectors.y, crossVectors.z).normalize());
this.mesh.geometry.rotateX(rotateX);
} else if (crossVectors.x < 0 && crossVectors.y > 0 && crossVectors.z < 0) {
console.log('- + -');
var rotateX = new THREE.Vector3(0, 0, 100).normalize().angleTo(new THREE.Vector3(0, crossVectors.y, crossVectors.z).normalize());
this.mesh.geometry.rotateX(rotateX);
} else if (crossVectors.x < 0 && crossVectors.y > 0 && crossVectors.z > 0) {
console.log('- + +');
var rotateX = new THREE.Vector3(0, 0, 100).normalize().angleTo(new THREE.Vector3(0, crossVectors.y, crossVectors.z).normalize());
this.mesh.geometry.rotateX(rotateX);
}
else {
alert('IMPOSSIBLE TO ALIGN');
}
And the last step align the 2 and 3 point, calculating the angle beween.
I there any solution for that?
Really thanks guys, i'm getting a little crazy, i'm new on that.
I would like to have a simpler code for that, i'm 90% sure it exists a better way to do that.
The idea is to have the object on the plane aligned by the 3 points:
Desired result, as you can see the foot is aligned with the floor plane.
Really thanks!

I have solved this with the response of #WestLangley, really thanks for your help.
There is the code to align the mesh to match the plane:
let subvector1, subvector2, crossVectors = new THREE.Vector3();
// Create the cross vector with the 3 points
subvector1.subVectors(this.aligningPoints[0], this.aligningPoints[2]);
subvector2.subVectors(this.aligningPoints[0], this.aligningPoints[1]);
crossVectors.crossVectors(subvector1, subvector2);
// Move the mesh (0,0,0) plane
this.mesh.geometry.applyMatrix4(new Matrix4().makeTranslation(-this.aligningPoints[0].x, -this.aligningPoints[0].y, -this.aligningPoints[0].z))
// Align the mesh to the plane with quaternion and matrix4
const quaternion = new THREE.Quaternion();
quaternion.setFromUnitVectors( crossVectors.normalize(), new THREE.Vector3(0,0,1).normalize() );
let matrix4 = new THREE.Matrix4()
matrix4.makeRotationFromQuaternion( quaternion );
this.mesh.geometry.applyMatrix4( matrix4 );

Related

Cannot read property 'add' of null

Hi all something wrong with my programming here as getting an error even though shape is drawn, but I can see it;s not quite right sketch
var circle= new Path.Circle({
radius: 100,
position: [200,200]
})
splat= new Path()
splat.fillColor= 'pink'
var count= 20
var length= circle.length
for(var i = 0; i <= count + 1; i++){
var offset= i / count * length
const normal = i === 0 || i === count
? new Point(0, 0)
: circle.getNormalAt(offset) * (Math.random() * 50);
const point = circle.getPointAt(offset).add(i % 2 == 0 ? normal
: -normal);
console.log(point)
splat.add(point)
splat.smooth({ type: 'catmull-rom', factor: 0.5 });
}
Thanks in advance
Your for loop stop condition is wrong:
i <= count + 1 should be either:
i < count + 1
i <= count
Otherwise when i is equal to count + 1, offset value is over length value and circle.getPointAt(offset) returns null.

How setup a Max Width and Height resizing for those shape?

I've seen this code that builds, my attention is to fix the resizing of those shape, and when I move them how can I block the shape to not move out of the window ?
I tried to fix resizing to not exceed when x is between 100 and 300, it works but when I try to decrease the shape size it does not move any more
static void enableDrag(Circle node, boolean canDragX, boolean canDragY, DragHandler dragHandler) {
final Delta dragDelta = new Delta();
node.setOnMousePressed(mouseEvent -> {
// record a delta distance for the drag and drop operation.
dragDelta.x = node.getCenterX() - mouseEvent.getX();
dragDelta.y = node.getCenterY() - mouseEvent.getY();
node.getScene().setCursor(Cursor.MOVE);
});
node.setOnMouseReleased(mouseEvent -> {
node.getScene().setCursor(Cursor.HAND);
});
node.setOnMouseDragged(mouseEvent -> {
double oldX = node.getCenterX();
double oldY = node.getCenterY();
System.out.println(node.getCenterX());
if(node.getCenterX()<=300 && node.getCenterX()>100){
System.out.println();
double newX = mouseEvent.getX() + dragDelta.x;
if (canDragX && newX > 0 && newX < node.getScene().getWidth()) {
node.setCenterX(newX);
}
double newY = mouseEvent.getY() + dragDelta.y;
if (canDragY && newY > 0 && newY < node.getScene().getHeight()) {
node.setCenterY(newY);
}
newX = node.getCenterX();
newY = node.getCenterY();
if (dragHandler != null && (newX != oldX || newY != oldY)) {
dragHandler.handle(oldX, oldY, newX, newY);
}
}
});
node.setOnMouseEntered(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
node.getScene().setCursor(Cursor.HAND);
}
});
node.setOnMouseExited(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
node.getScene().setCursor(Cursor.DEFAULT);
}
});
}

Shift A-Frame Origin

When I place a block at the origin it is very far back from my sensors. I wish to move the aframe origin forward 1 meter (1 in the -z direction). Additionally I am using a component which tracks the cameras position and so I cannot just wrap everything in an <a-entity> and move that forward. How can I change the position of the origin?
Component:
AFRAME.registerComponent('info-panel', {
tick: function() {
var el = this.el;
var camera = document.querySelector('a-camera');
var cpos = camera.getAttribute('position');
var x = cpos.x;
var z = cpos.z;
var angle;
if (z === 0) {
if (x === 0) {
angle = 0;
} else if (x > 0) {
angle = 90;
} else {
angle = -90;
}
} else {
angle = (z > 0 ? 0 : 180);
angle += 180 / Math.PI * Math.atan(x / z);
}
el.setAttribute('rotation', {x: 0, y: angle, z: 0});
}
});
Scene:
<a-scene>
    <a-camera></a-camera>
    <a-panel info-panel></a-panel>
</a-scene>
Or you can position the camera with wrapper entity.
How do a place the camera first position
<a-entity position="0 0 5">
<a-camera></a-camera>
</a-entity>
I'm not sure if there is such functionality,
I would wrap everything except the camera in <a-entity>
So You can position 'everything' except the camera.

How to keep my QMainWindow always inside of the desktop?

I want to keep my QMainWindow always inside of the desktop, so I add the implementation for QMainWindow::moveEvent :
void MainWindow::moveEvent(QMoveEvent *ev)
{
if(ev->pos().x() < 0) setGeometry(0, ev->oldPos().y(), width(), height());
}
But when I move the window to out of desktop left bounding, the app is crashed.
What is wrong with this code? Why it is crashed? Is my solution correct?
//--Update:
I tried with this:
int newx = ev->pos().x(),
newy = ev->pos().y();
if(ev->pos().x() < 0) newx = 0;
if(ev->pos().y() < 0) newy = 0;
move(newx, newy);
It worked without crash but I'm not satisfied because of the moving is not smooth.
This should smoothly help with the upper left corner .. but you'll need to add some more conditions to get it working for all four sides.
posX and posY are member variables.
void MainWindow::moveStep() { // [SLOT]
int movX = 0, movY = 0;
if(posX < 0) movX = 1;
if(posY < 0) movY = 1;
move(posX + movX, posY + movY);
}
void MainWindow::moveEvent(QMoveEvent *ev) {
if(ev->pos().x() < 0 || ev->pos().y() < 0) {
posX = ev->pos().x();
posY = ev->pos().y();
QTimer::singleShot(10, this, SLOT(moveStep()));
}
}
To have it even more elegantly consider using QVariantAnimation with a QRect and setGeometry().

Implementing a wall in get successor for A*

I have a get successor function C# which get the successor for Nodes in a grid
public ArrayList GetSuccessors()
{
ArrayList successors = new ArrayList ();
for (int xd=-1;xd<=1;xd++)
{
for (int yd=-1;yd<=1;yd++)
{
if ((xd != 0 && yd == 0) || (xd == 0 && yd != 0)) // to take only up - down - right - left
{
if (Map.getMap(x + xd, y + yd) != -1)
{
// generate a new node where the parent node is the existance, goal node, cost , x , y
Node n = new Node(this, this._goalNode, Map.getMap(x + xd, y + yd), x + xd, y + yd);
// to elemenat duplication
if (!n.isMatch(this.parentNode) && !n.isMatch(this))
successors.Add(n);
}
}
}
}
return successors;
}
for getMap function it's just return if the value inside the map 1 or -1 if it's 1 then I take this node if it's -1 then No it's an obstacles.
My question is how I can implement a condition so that if there is a wall between
[0,0] and [0,1] in the grid don't take [0,1] as a successor for [0,0]
thank you

Resources