I have a flex plotchart and I need an animation that would enable me to move datapoints from 1 location to another. The actual movement must also be shown.
I have tried move control but the call to play() does not work.
Any hints would also help greatly..
Thanks in advance
After much effort, I found that one way to move the point from 1 point to another is by making it move along the equation of the line and rendering the intermediate points on the graph after some delay...
I'll share the code...
Place the following line where you want to start the movement:
setTimeout(showLabel,singleDuration,oldLocation,newLocation,
Constants.TOTAL_STEPS,1,oldLocation.x, oldLocation.y, singleDuration);
And this is the function definition:
private function showLabel(oldLoc:Object newLoc: Object, totalSteps: Number,
count:Number, currentX: Number, currentY: Number, singleDuration: Number): void{
tempArrColl = new ArrayCollection();
var tempObj: Object= new Object();
xDelta = 0.25;
yDelta = 0.25;
tempObj.x = currentX + (xDelta * count);
tempObj.y = currentY + (yDelta * count);
if ((tempObj.x >= newLoc.x) || (tempObj.y >= newLoc.y)){
tempObj.x = newLoc.x;
tempObj.y = newLoc.y;
callLater(showPoint,[tempObj]);
tempArrColl = new ArrayCollection();
plotGraphArrayColl.addItem(newLoc);
return;
}
callLater(showPoint,[tempObj]);
count++;
setTimeout(showLabel, singleDuration, oldLoc, newLoc,
totalSteps, count, tempObj.x, tempObj.y, singleDuration);
}
private function showPoint(loc: Object): void {
tempArrColl.addItem(loc);
plotChart.validateNow();
}
Here, tempArrColl will hold the intermediate point along the line equation. Put it as a dataProvider in a series on the graph and then once all the points are moved, remove it. plotGraphArrayColl is the dataProvider that would hold the newly moved points..
There may be better ways possible but it worked for me... Do tell if anyone finds something easier.. Thanks
Related
I tried to use the method setTransform like this:
#override
void update(double dt) {
super.update(dt);
increaseTimer.update(dt);
if (side == 3) {
body.setTransform(Vector2(0, gameRef.increasedHeight), 0);
}
}
But the item looks like it is flashing from point A to point B, and the Items above this body are falling. I just want this body and the items above to move smoothly in a direction , how to achieve this? Thanks, I found some methods like using MouseJoint, but I guess it is too complicated for my topic?
=========UPDATE==========
Hi spydon, thanks for reply, I checked your answer, sry I didnt describe my question clearly.
The item I want to keep moving upward is like a wall/ground so it is a static body, therefore applyLinearImpulse/applyForce does not work right (since these both works only for dynamic body?).
Therefore I found setTransform, which works for static body,
increasedHeight++; //<= in update method
body.setTransform(Vector2(0, increasedHeight), 0);
works fine which make my ground move upward in 1 unit, but if the distance is larger than 1 unit, like
increasedHeight = increasedHeight + 10;,
the ground will be beamed to top and balls on this ground will be falling, which I don't want to, I tried to make balls and ground move together upward, is it possible?
Thanks for your time!
=========2.UPDATE==========
Hi Spydon, thanks again for your help! Plz check the example I created, since this Ground didn't move upward as I expected and just stuck in the position ...
class Ground extends SpriteBodyComponent {
Vector2 groundPosition;
bool removed = false;
final velocity = Vector2(0, 1000);
Ground({Sprite sprite, Vector2 size, this.groundPosition}) : super(sprite, size);
#override
Body createBody() {
final shape = CircleShape()..radius = size.x / 4;
var position = groundPosition.clone();
var worldPosition = viewport.getScreenToWorld(position);
final fixtureDef = FixtureDef()
..shape = shape
..restitution = 0.1
..density = 0.1
..friction = 0.1;
final bodyDef = BodyDef()
..userData = this
..angularDamping = 0.1
..position = worldPosition
..type = BodyType.STATIC;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
#override
void update(double dt) {
super.update(dt);
body.setTransform(velocity * dt, 0);
print('body position == ${body.position.y}'); //<= body position == 16.667
}
}
You should almost never use setTransform on dynamic bodies, since this disturbs the physics calculations. If you are not certain that you need the physics simulation you most likely want to go with pure Flame and use one of the MoveEffects instead.
If you do need Forge2D, you should either use body.applyLinearImpulse or body.applyForce, depending on how you want to affect your bodies movement.
You can read more about it here and you can check out the flame_forge2d examples here, you can get to the code for each example by pressing < > in the upper right corner.
Reply to updated question:
You should change these things in your update method which gives you a delta time dt, this delta time you use together with the velocity that you want to the body to change with, for example:
final velocity = Vector2(0, 100); // Will move with 100px/s
#override
void update(double dt) {
if(!velocity.isZero) {
// Here you have to multiply with dt, to make the transform become px/s
body.setTransform(velocity * dt, 0);
}
}
My setup method looks like below, I want to read one location file(City names with x and y co-ordinates) and then I am creating one hash-map of all cities so that I can draw(Will make points) them all on canvas
public void setup(){
background(0);
PFont title = createFont("Georgia", 16);
textFont(title);
text("This is a visualization of A* algorithm", 240, 20);
stroke(255);
line(0,25,800,25);
selectInput("Select a file for Locations:", "locFileSelected");
}
locFileSelected method(locFilePath is a global variable used):
public void locFileSelected(File locFile) {
locFilePath = locFile.toString();
this.readLocFileAndDraw();
}
Now control is transferred to readLocFileAndDraw (Each line in file has space separated 3 words, 1st is city name followed by x and y co-ordinates:
private void readLocFileAndDraw() {
try (Stream<String> lines = Files.lines(Paths.get(locFilePath))) {
for (String line : (Iterable<String>) lines::iterator){
// Last line in file is END, skip it
if(!line.equalsIgnoreCase("END")) {
List<Double> list = new ArrayList<Double>();
String[] arr= line.split(" ");
// adding coordinates into the list
list.add(Double.valueOf(arr[1]));
list.add(Double.valueOf(arr[2]));
// adding the list into the map with key as city name
locationsMap.put(arr[0], list);
}
}
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
// Draw cities on map
// Draw graph of all cities
int w=1, h=1;
Set<Entry<String, List<Double>>> locationKeyEntries = locationsMap.entrySet();
for(Entry<String, List<Double>> currEntry: locationKeyEntries) {
String currCity = currEntry.getKey();
List<Double> currLocationList = currEntry.getValue();
int x = currLocationList.get(0).intValue();
int y = currLocationList.get(1).intValue();
stroke(255);
ellipse(x, y, w, h);
if(x>755)
x = x-(8*currCity.length());
if(y>755)
y=y-(8*currCity.length());
text(currCity, x,y);
}
return;
}
I tried to debug it, control is going to ellipse method but nothing is getting drew. Any idea? As far as I understand, I am missing passing reference of PApplet but I don't know how to do it...
Like you've mentioned, you really need to debug your program. Verifying that you're calling the ellipse() function is a great first step, but now you should be asking yourself more questions:
What is the value of x, y, w, and h being passed into the ellipse() function?
What is the value of currEntry in the for loop? What is the value of line when you're reading it in?
What are the fill, stroke, and background colors when you're drawing?
Note that I'm not asking you to tell me the answer to these questions. I'm pointing out these questions because they're what you should be asking yourself when you debug your program.
If you still can't figure it out, I really recommend breaking your problem down into smaller pieces and approaching each of those steps one at a time. For example, can you just show a single circle at a hard-coded point? Then work your way up from there. Can you read a single point in from a file and draw that to the screen? Then read two points. Work your way forward in small incremental steps, and post a MCVE if you get stuck. Good luck.
Attempting to get the user's height in Unity using the xbox kinect.
Below is my code and I cannot get the height.
This uses the KinectV2 interface.
// get User's height by KinectV2 and unity3D `enter code here`
float GetUserHeightByLeft(long userid)
{`enter code here`
float uheight=0.0f;
int[] joints = new int[9];
int head = (int)KinectInterop.JointType.Head;
joints[0] = head;
joints[1] = (int)KinectInterop.JointType.Neck;
int shoudlderCenter = (int)KinectInterop.JointType.SpineShoulder;
joints[2] = shoudlderCenter;
joints[3] = (int)KinectInterop.JointType.SpineMid;
joints[4] = (int)KinectInterop.JointType.SpineBase;
joints[5] = (int)KinectInterop.JointType.HipLeft;
joints[6] = (int)KinectInterop.JointType.KneeLeft;
joints[7] = (int)KinectInterop.JointType.AnkleLeft;
joints[8] = (int)KinectInterop.JointType.FootLeft;
int trackedcount = 0;
for (int i = 0; i < joints.Length; ++i)
{
if (KinectManager.Instance.IsJointTracked(userid, joints[i]))
{
++trackedcount;
}
}
//if all joints that I need have been tracked ,compute user's height
if (trackedcount == joints.Length)
{
for (int i = 0; i < joints.Length-1;++i)
{
if (KinectManager.Instance.IsJointTracked(userid, joints[i]))
{
Vector3 start= 100*KinectManager.Instance.GetJointKinectPosition(userid,joints[i]);
Vector3 end = 100*KinectManager.Instance.GetJointKinectPosition(userid,joints[i+1]);
uheight += Mathf.Abs(Vector3.Magnitude(end-start));
}
}
//some height kinectV2 can't get so I add it
uheight += 8;
}
return uheight;
}
Given your code I do see a few issues
The summation to get the total height requires all joints to be tracked at that time.
Why do you need all joints to be tracked for the height to be tracked? You should only need the head and the feet
You double check if each joint is tracked
using the left for every foot/knee/hip joint is going to give you math errors. They are offset in one direction (because our feet aren't in the center of our body)
I would track both right and left foot/knee/hip and then find the center of the two on the x axis.
If you're using the magnitude of two vectors and one knee is far in front of your hip it's going to give it an inflated value.
I would only use the y positions of your kinect joints to calculate the height.
I am newbie in Unity platform. I have 2D game that contains 10 boxes vertically following each other in chain. When a box goes off screen, I change its position to above of the box at the top. So the chain turns infinitely, like repeating Parallax Scrolling Background.
But I check if a box goes off screen by comparing its position with a specified float value. I am sharing my code below.
void Update () {
offSet = currentSquareLine.transform.position;
currentSquareLine.transform.position = new Vector2 (0f, -2f) + offSet;
Vector2 vectorOne = currentSquareLine.transform.position;
Vector2 vectorTwo = new Vector2 (0f, -54f);
if(vectorOne.y < vectorTwo.y) {
string name = currentSquareLine.name;
int squareLineNumber = int.Parse(name.Substring (11)) ;
if(squareLineNumber < 10) {
squareLineNumber++;
} else {
squareLineNumber = 1;
}
GameObject squareLineAbove = GameObject.Find ("Square_Line" + squareLineNumber);
offSet = (Vector2) squareLineAbove.transform.position + new Vector2(0f, 1.1f);
currentSquareLine.transform.position = offSet;
}
}
As you can see, when I compare vectorOne.y and vectorTwo.y, things get ugly. Some boxes lengthen and some boxes shorten the distance between each other even I give the exact vector values in the code above.
I've searched for a solution for a week, and tried lots of codes like Mathf.Approximate, Mathf.Round, but none of them managed to compare float values properly. If unity never compares float values in the way I expect, I think I need to change my way.
I am waiting for your godlike advices, thanks!
EDIT
Here is my screen. I have 10 box lines vertically goes downwards.
When Square_Line10 goes off screen. I update its position to above of Square_Line1, but the distance between them increases unexpectedly.
Okay, I found a solution that works like a charm.
I need to use an array and check them in two for loops. First one moves the boxes and second one check if a box went off screen like below
public GameObject[] box;
float boundary = -5.5f;
float boxDistance = 1.1f;
float speed = -0.1f;
// Update is called once per frame
void Update () {
for (int i = 0; i < box.Length; i++) {
box[i].transform.position = box[i].transform.position + new Vector3(0, speed, 0);
}
for (int i = 0; i < box.Length; i++)
{
if(box[i].transform.position.y < boundary)
{
int topIndex = (i+1) % box.Length;
box[i].transform.position = new Vector3(box[i].transform.position.x, box[topIndex].transform.position.y + boxDistance, box[i].transform.position.z);
break;
}
}
}
I attached it to MainCamera.
Try this solution:
bool IsApproximately(float a, float b, float tolerance = 0.01f) {
return Mathf.Abs(a - b) < tolerance;
}
The reason being that the tolerances in the internal compare aren't good to use. Change the tolerance value in a function call to be lower if you need more precision.
I have created a basic as3 web project with starling. All iam doing is creating a simple image and in onEnterframe moving the image along x. But it seems that the animation/movement is not smooth, there is a jump in frames/jerkiness after every few frames. Below is onEnterFrame and the test function used to create the image. Any help on this is much appreciated.
private function onEnterFrame(e:Event):void
{
if(!img)
return;
img.x += 1;
if(img.x >= 960)
img.x = 0;
}
private function test():void
{
img = new Image(sAssets.getTextureAtlas("atlas").getTexture("flight_00"));
addChild(img);
img.x = 0;
img.y = 320;
}
That's because the time of each frame is slightly different. To achieve smooth animation, declare onEnterFrame handler with passedTime argument (that stores the time passed since previous frame) and use this value to move objects, instead of assuming that each frame will last 1/frameRate sec.
private function onEnterFrame(passedTime:Number):void
{
if(!img)
return;
img.x += passedTime * 100; // speed is 100 px/sec
if(img.x >= 960)
img.x = 0;
}
Note: this form of event handlers (without event argument) is supported in recent versions of Starling, and should be more performant. If you use older version, you can obtain passed time from the corresponding property of event object.