When I am trying to use :
var arrow = new THREE.ArrowHelper(direction, startPoint, startPoint.distanceTo(endPoint), 0xCC0000 );
scene.add(arrow);
it basically uses a point rather than an object. Does anyone know how to join to objects directly in three.js?
Okay without code to plug into I'll provide the steps in Pseudo code:
1) Create 2 THREE.SphereGeometry, matching Materials, apply them to a THREE.Mesh aptly named.
2) Store a point from each Sphere via: sphere1.geometry.vertices[0] or whatever point index you feel works best.
3) Use those points to build your THREE.ArrowHelper
That should get you going. Of course the next steps look something like this:
4) Detect user intersect with each Sphere (look up Raycaster example)
5) Build move logic to reposition your Sphere
6) Update the scene objects to reflect the new positions
Hope that helps,
D
Related
I have a list of points in the field (like upper_goal_point/ left_upper_outer_corner, etc.
I know their corresponding coordinates in destination image - so I can calculate the homography:
h, status = cv2.findHomography(pts_src, pts_dst)
I also have blue points in the upper corner line (look at image above), which I only know that their destination's y coordinates are 0 (because they are in the upper line), but I don't know where exactly they lay in that line.
Can I use those blue points in order to improve the homography?
P.S.
You can see that the upper corner line in the homography is not horizontal line, it's diagonal, which of course is not correct:
Actually it possible to use line correspondence in find homography.
https://www.researchgate.net/publication/220845575_Combining_Line_and_Point_Correspondences_for_Homography_Estimation
Several years ago we implement this approach in one project. During simplification all math we come up with simple trick. We transform every line a*x + b*y + c = 0 to point (a/c, b/c)
// *** Don't copy paste this code, read below! ***//
Point2f convertPointsToHomogeneousLine(Point2f p1, Point2f p2) {
Point3f p1h(p1.x, p1.y, 1);
Point3f p2h(p2.x, p2.y, 1);
Point3f lineHomo(p1h.y*p2h.z - p1h.z*p2h.y,
p1h.z*p2h.x - p1h.x*p2h.z,
p1h.x*p2h.y - p1h.y*p2h.x);
Point2f lineHomoNorm(lineHomo.x / lineHomo.z,
lineHomo.y / lineHomo.z);
return lineHomoNorm;
}
And pass this points inside. As I remember I also dig inside OpenCV implementation of findHomography and insert this lines somewhere inside to solve step. Inside OpenCV there some normalization applied to points before pass to solve step. So you need to skip this step for this kind of points.
We do not use it in production. User need to calibrate camera manually by providing lines and points on the image and in meter system. It has too complicated interface and bad stability. But in your case I think it can work better. If you will automatically find lines and correspondence.
P.S. Please note that in paper they use some normalization technique.
It will improve stability. We faced with stability problem, do not
solved it in our journey.
I'm working on a program in Godot using Gdscript, and I ran into a problem when trying to use the Transform.translated(Vector3) function. My code is supposed to move a bone to (0,0,0) by translating it by its current coordinates but with negative sign. Example: (1,2,3) would be translated by (-1,-2,-3) so it would end up at (0,0,0). For some reason when I do this, the end position of the bone is not (0,0,0), but some other coordinate. In the Godot documents, it says the .translated function is "relative to the transform's basis vectors", so maybe that's why? Also if there is a better way to change a bones position than using the Transform.translated(Vector3) function that would be helpful too. Thanks!
My Code:
bonePose = skel.get_bone_global_pose(bone)
var globalBonePose = skel.to_global(bonePose.origin)
translateVector = -globalBonePose
var newPose = bonePose.translated(translateVector)
skel.set_bone_pose(bone, newPose)
Code Output / Results:
bonePose (the original position of the bone) is around (-0.82,0.49,0.50)
translateVector (the amount the bone will be translated) is around (0.82,-0.49,-0.50)
newPose (the final position of the bone -- should be [0,0,0]) is around (0.82,-0.66,-0.46). Even when I call skel.to_global(newPose.origin) to see the global coordinates, it's (-0.76,0.44,0.42), which is not (0,0,0)
In Godot a Transform is composed of a basis (a Basis) and an origin (a Vector3). Where the origin handles the translation part of the transform, and the Basis the rest.
A Basis is the set of vectors that define the coordinate system. There is a vector that defines the x axis, another for the y axis, and another for the z axis. And this is the way Godot will encode rotation and scaling transformations.
When the documentation says "relative to the transform's basis vectors" it means the Basis will be applied to the vector you pass in. Thus, in your case, you are getting a translation on the local space of the bone. Which implies that if the bone is rotated or scaled (or something like that), that will affect the translation.
If you don't want to deal with rotation, scaling, et.al. I suggest you work with the origin of the Transform instead.
If you have a Transform and you want another that is otherwise equal but located at (0, 0, 0), you do this:
var new_transform = Transform(transform.basis, Vector.ZERO)
Or replace Vector.ZERO with whatever origin you want to give the new transform.
I also need to remind you that get_bone_global_pose and set_bone_pose do not operate on the same thing. On one hand set_bone_pose is relative to the parent bone, on the other get_bone_global_pose is relative to the Skeleton. Thus, I suggest you use set_bone_global_pose_override instead.
The final piece you need is the opposite of Spatial.to_global. Because setting the pose like as follows…
bonePose = skel.get_bone_global_pose(bone)
var newPose = Transform(bonePose.basis, Vector.ZERO)
skel.set_bone_global_pose_override(bone, newPose, 1.0)
… Would place it at the origin of the Skeleton.
Well, the opposite of Spatial.to_global is Spatial.to_local, and you would use it like this:
bonePose = skel.get_bone_global_pose(bone)
var newPose = Transform(bonePose.basis, skel.to_local(Vector.ZERO))
skel.set_bone_global_pose_override(bone, newPose, 1.0)
Here skel.to_local(Vector.ZERO) should give the origin of the world relative to the Skeleton. And given that set_bone_global_pose_override wants a Transform relative to the Skeleton, the result should be that the bone is placed at the origin of the world. With its rotation and scaling preserved.
I'm writing a program in Godot with GDscript that aims to change the position of multiple bones in an armature. The bone gets translated by a value calculated by the point I want the bone to move to minus the current position of the bone. translateValue = endPoint - currentPoint However, all values must be in world coordinates or global position for the code to work. Godot has various methods to retrieve the bone Transform in order to access the position such as : skeleton.get_bone_pose() , skeleton.get_bone_global_pose , skeleton.get_bone_rest . I tried using skeleton.get_bone_global_pose but it didn't give the global position and seemed to still be relative to something. There's also the to_global() method, but i'm not entirely sure what it does. Could someone explain the differences between these methods and how to get global position? Thanks!
I'll start with these methods:
get_bone_rest
get_bone_custom_pose
get_bone_pose
First of all, get_bone_rest gives you the default transform of the bone, relative to its parent bone. Then the other transform are stacked, in the above order.
Then we have:
get_bone_global_pose
This method gives you the final transform of the bone. And it is relative to the Skeleton. That is, this transform already includes the previously mentioned transforms, combined from parent to child bone.
Thus, converting its result to world space is a matter of composing the transform of the Skeleton:
$Skeleton.global_transform * $Skeleton.get_bone_global_pose(bone_index)
And we have:
get_bone_global_pose_no_override
As the name suggest get_bone_global_pose_no_override ignores any global pose override. That's right, you you can override the global pose. To do that, use set_bone_global_pose_override. See also clear_bones_global_pose_override. These are all, of course, relative to the Skeleton.
The method Spatial.to_global(vector3) is unrelated to the Skeleton. It transforms a vector from the local space of the node on which you call it, to world space. Which might also be useful:
$Skeleton.to_global($Skeleton.get_bone_global_pose(bone_index).origin)
I need to interpret an SVG input data and identify the displayed points.
In the SVG format, any point may be part of a group ( element ) to which transformations (translate/rotate/scale) may be applied. For every point, I need to bubble up and apply transformation of every ancestor, in order to find the position that the point has in the rendering. After reading some web pages on the subject (and trying to remember from school), I understand that the usual way to do this in .NET is to use 3x3 mathematical matrices, so I try to figure out the System.Windows.Media.Matrix class.
It's been a while since I took Math, and I can't recall this one particular detail.
I typed up the following code in LINQPad:
var matrix = new Matrix(1,1,1,6,0,0);
var matrix2 = new Matrix(2,1,0,6,0,0);
var matrix3 = new Matrix(0,1,2,6,0,0);
var pts = new[]{
new System.Windows.Point(0,0),
new System.Windows.Point(1,1),
new System.Windows.Point(2,2),
new System.Windows.Point(3,3),
new System.Windows.Point(4,4),
new System.Windows.Point(5,5)
}.ToArray();
pts.Select(org=>new{org,changed=matrix.Transform(org),changed2=matrix2.Transform(org),changed3=matrix3.Transform(org)}).Dump("Transformation Samples");
... and trying out different values in the Matrix constructor.
However it seems that these values have no impact on the final result.
new Matrix(1,1,1,6,0,0);
new Matrix(2,1,0,6,0,0);
new Matrix(0,1,2,6,0,0);
(same is true for arguments 2 and 4)
The only thing that seems to matter is the sum of the two (which in this case is 2). I assume that this is due to my limited input data and that given other input data, some difference could be seen that would make sense in some visual tranformation.
Can anybody help me out here?
Perhaps the section in the SVG spec about how transform matrixes work will be of use to you?
http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined
I have a path defined in SVG. I would like to make two copies of the path and translate them so that one sits parallel to the original on one side, and the other sits parallel on the other side. The idea is to end up with 3 paths, all parallel to each other and not overlapping.
I have tried simple translations such as transform="translate(10,10)" and transform="translate(-10,-10)" for the two paths, but in some paths they end up crossing each other which is not what I want.
Thanks.
Your answer should somewhat work as you've provided it. You might provide more concrete examples of your problem to evoke better solutions.
Your provided commands are going to move the item in two dimensions, not just one.
Also, keep in mind that SVG uses the upper left point as 0,0, and to the right/down are positive. Also check to make sure you're not getting tripped up by units.
If your original path has a bounding box of X,Y then the simplest way to make sure that the copied don't overlap is to translate by +X and -X, so:
translate(-X, 0)
and
translate(X, 0)
where you have computed the value of X and set it in the translate argument.
I'll give you some completely untested code written without looking at the SVG DOM spec. You can then test it and tweak it to get it to work.
First, get the bounding box of an element:
var box = mypath.getBBox();
Then clone the path twice (or make elements):
var rightCopy = mypath.cloneNode(true);
var bottomCopy = mypath.cloneNode(true);
Then transform each copy:
rightCopy.setAttribute("transform", "translate(" + box.width + ",0) " + rightCopy.getAttribute("transform"));
bottomCopy.setAttribute("transform", "translate(0," + box.height + ") " + bottomCopy.getAttribute("transform"));
The reason it looks messy is because the original path might have a transform already on it.
Then add those nodes back into the DOM:
mypath.parentNode.insertBefore(rightCopy, mypath);
mypath.parentNode.insertBefore(bottomCopy, mypath);