What happens if i a make a rotation on a scenekit node object this way:
node.rotation = SCNVector4Make(1, 0, 0, M_PI_2)
Does it adds PI/2 to existing rotation or does it set object angle to PI/2?
In other words what happens if i call twice this line:
node.rotation = SCNVector4Make(1, 0, 0, M_PI_2)
Does it rotate to PI/2 or PI ?
I have the same question for node.eulerAngles property
Thanks
none of the SCNNode properties regarding transforms is "cumulative", just like the transform of a CALayer for instance. To combine transforms you'll want to use utils such as SCNMatrix4Rotate.
While I'll never argue with what is in SceneKit with mnuages (I think he works on it at Apple), I will contend that he's taken your question too literally.
If you are looking for cumulative rotation, it is available in SceneKit, if you know how much rotation you want. You can use the two rotateBy SCNActions.
They are :
rotateBy(x:y:z:duration:)
and:
rotate(by:around:duration:)
Both of these, applied repeatedly, will cumulatively add to the rotation of your object.
Related
I'm trying to point a circle with arrow at the top at an scnnode in scenekit, but keep it constrained or flat toward the point of view at all times. It seems that with a look at constraint, the billboard constraint gets ignored.
Here is the setup for constraints:
let billboardConstraint = SCNBillboardConstraint ()
billboardConstraint.freeAxes = SCNBillboardAxis.Y
let lookatConstraint = SCNLookAtConstraint ( target: targetNode )
lookatConstraint.localFront = SCNVector3Make ( 0, 1, 0 )
lookatConstraint.worldUp = SCNVector3Make ( 0, 1, 0 )
arrowNode.constraints = [billboardConstraint, lookatConstraint]
self.sceneView.pointOfView?.addChildNode ( arrowNode )
Here are example images of the issue. The first image is how I want to keep it, the second image shows the flattening that I can't seem to control:
No matter what I try, it doesn't stay facing the camera. I've tried equating the z distance for both the arrow node and the target node (still rotates the arrow node undesirably), tried setting a gimbal lock (flips the arrow node out), tried to adjust the angles for the arrow node to keep it "facing" the point of view, and tried an SCNCone as a pointer.
I also tried just moving this arrow node into an imageview in the overlay, with an invisible arrow node inside Scenekit, but couldn't get the math right when trying to CGAffineTransform the 2d UIImageView. I tried getting the rotation vector for the SCNNode that has the SCNLookatConstraint, tried projectpoint, etc. Not quite getting it. Maybe I should've paid more attention in high school :-(
Anyone have any ideas:
This post: 59251351 - it's like a 3d box with a tube (a tank with a gun), that targets a specific node - "aims" at it. That's your arrow, so first - make sure that you have set it up with the correct rotation from the beginning, otherwise it will never work. Arrow should be a subnode so that your main node and all subnodes rotate together as you set the constraints for the main node.
The example is a fixed -z for related nodes and the point of view doesn't change. Assuming you want to move the camera forward, then you need a way to maintain perspective - that's keeping Z for all in question at the same distance from the camera.
So, if your target node and indicator can stay on the same z distance plane (as you indicated in your example that it can work that way), I "think" this should help. You might set your target node slightly off on z compared to your arrrow nodes, something insignificant such as .001 - just so the lookAt math doesn't actually return a (NAN) though some happenstance.
If it's more complex than that, then someone with more math skills is required.
Hope that helps
I'm recently playing with glPolygonOffset( factor, units ) and find something interesting.
I used GL_POLYGON_OFFSET_FILL, and set factor and units to negative values so the filled object is pulled out. This pulled object is supposed to cover the wireframe which is drawn right after it.
This works correctly for pixels inside of the object. However for those on object outline, it seems the filled object is not pulled and there is still lines there.
Before pulling the filled object:
After pulling the filled object:
glEnable(GL_POLYGON_OFFSET_FILL);
float line_offset_slope = -1.f;
float line_offset_unit = 0.f;
// I also tried slope = 0.f and unit = -1.f, no changes
glPolygonOffset( line_offset_slope, line_offset_unit );
DrawGeo();
glDisable( GL_POLYGON_OFFSET_FILL );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
DrawGeo();
I read THIS POST about the meaning and usage of glPolygonOffset(). But I still don't understand why the pulling doesn't happen to those pixels on border.
To do this properly, you definitely do not want a unit of 0.0f. You absolutely want the pass that is supposed to be drawn overtop the wireframe to have a depth value that is at least 1 unit closer than the wireframe no matter the slope of the primitive being drawn. There is a far simpler approach that I will discuss below though.
One other thing to note is that line primitives have different coverage rules during rasterization than polygons. Lines use a diamond pattern for coverage testing and triangles use a square. You will sometimes see software apply a sub-pixel offset like (0.375, 0.375) to everything drawn, this is done as a hack to make the coverage tests for triangle edges and lines consistent. However, the depth value generated by line primitives is also different from planar polygons, so lines and triangles do not often jive for multi-pass rendering.
glPolygonMode (...) does not change the actual primitive type (it only changes how polygons are filled), so that will not be an issue if this is your actual code. However, if you try doing this with GL_LINES in one pass and GL_TRIANGLES in another you might get different results if you do not consider pixel coverage.
As for doing this simpler, you should be able to use a depth test of GL_LEQUAL (the default is GL_LESS) and avoid a depth offset altogether assuming you draw the same sphere on both passes. You will want to swap the order you draw your wireframe and filled sphere, however -- the thing that should be on top needs to be drawn last.
Good eve all!
I'm making simple model editor on WPF for creating cube-head freaks with pixelate skins and want add billboarding to it.
So, what I do
Vector3D unitZ = new Vector3D(0, 0, 1);
Vector3D direction = -this.camera.LookDirection;
double yaw = Vector3D.AngleBetween(unitZ, new Vector3D(0, 0, direction.Z));
and the apply rotation to plane.
It works, but only on half, couse AngleBetween function allways returns positive values.
So when I rotate parent shape to -45 degrees AngleBetween returns 45 and it annihilate parent rotation. But when I rotate parent on 45 degrees AngleBetween again returns 45 and in result I got 90 degrees rotation.
Any solutions?
And one more thing: please, do not offer any frameworks or toolkits! Thanks.
Well, that's how AngleBetween method works for 3D vectors in WPF. It returns value in the range of [0..180] degrees.
As far as your problem goes, I am not 100% I understand you. The angle between [0, 0, 1] and [0, 0, arbitrary number here] can only give you three different values: :
impossible to calculate
180
0
-180 if signed is possible.
As I don't really see how you can ever get 45.
Either way, it's possible that you can use Vector.AngleBetween which should preserve the sign. That will work if your rotation is only on one axis, eg one of the components stay the same.
If that does not suit your needs, you should just write what you need: Signed angle between two 3D vectors with same origin within the same plane
I am looking for suggestions as how to create plots similar to GitHub punch cards with JFreeChart. E.g.
I guess it's some variant of a heat map, or two dimensional histogram.
Ok, so I found XYBubbleRenderer which looks like a good starting point.
create a MatrixSeries with rows = 7, columns = 24
fill in the frequencies accordingly. I found it useful to normalise the values first to 0...1, then take the square root (smaller values have a bit better visible circles), then multiply by 0.5 (otherwise the circles are too large)
create a MatrixSeriesCollection from that
use ChartFactory.createBubbleChart
the circle outline can only be removed via plot.getRenderer.setSeriesOutlinePaint(0, new Color(0, 0, 0, 0))
ensure integer tick units on both axis
x-axis range -0.5 to 23.5, y-axis range -0.5 to 6.5 (or 0.5 to 7.5 if you use Calendar.DAY_OF_WEEK)
custom NumberTickUnit for the y-axis to use day labels instead of numbers
The result:
In addition to XYBubbleRenderer, suggested here, also consider a suitable implementation of TableCellRenderer and Icon, illustrated here.
I have a "FlattenedPathGeometry" and I want to be able to get a specific point.X from the path based on a specific Point.Y
Basically I just need the X value at any given Y.
Thanks in advance for any help.
GetFlattenedPathGeometry gives you back a polygonal so basically you have to consider loop all the points and calculating the minimum distance to your point.
If you can make any assumption on the Geometry shape or your point, you can speed up the search.
For example if the path is very long, you can speed up by intersecting the shape with a circle/square centered in your point. This limit the number of points of the shape to test but be careful that the intersection method is very expensive. You'll have to measure the performances with a stopwatch to understand what's better in your case.