I have used the below method but it shows error on Swipe() method. This method is not available in driver class. So, please suggest if any other way we can scroll in iOS Appium v1.7.2.
Dimension size = driver.manage().window().getSize();
int x = size.getWidth() / 2;
int starty = (int) (size.getHeight() * 0.60);
int endy = (int) (size.getHeight() * 0.10);
driver.swipe(x, starty, x, endy, 2000);
For latest versions of appium you cannot use .swipe() because this method is deprecated.You have to achieve the scroll functionality in latest appium using TouchAction class.
Please refer the below link on Touch Actions :
Touch Actions in Appium
You can use the below method,
/**
* Swipe vertically upwards
*
* #author xxx
*
* #param ele
* -reference field/area to swipe
*
*/
public void verticalSwipe_Up(MobileElement ele) {
Dimension size = ele.getSize();
ElementOption press = element(ele, size.width / 2, (int) (size.height * .80));
ElementOption move = element(ele, size.width / 2, 25);
TouchAction swipe = new TouchAction(getDriver()).press(press).waitAction(waitOptions(Duration.ofMillis(1000))).moveTo(move).release();
// ofSeconds(2)
swipe.perform();
}
You can change the values accordingly to perform swipe down/right/left
Related
GetComponent<Rigidbody2D>().AddForce(transform.forward * Time.deltaTime * forceGathered, ForceMode2D.Impulse);
does not make gameobject move in 2D Unity.
I would like to make force gameobject according to another game object's rotation direction.
GetComponent() requires a parameter, in your case Rigidbody2D, so it should be like this:
GetComponent(typeof(Rigidbody2D)).AddForce(transform.forward * Time.deltaTime * forceGathered, ForceMode2D.Impulse);
...and the shorter version would be:
GetComponent<Rigidbody2D>().AddForce(transform.forward * Time.deltaTime * forceGathered, ForceMode2D.Impulse);
Also, I would recommended you to cache the Rigidbody2D component as it can get very expensive to use GetComponent() every time you need to access it.
It would be better to cache it on start:
Rigidbody2D rg;
void Start(){
rg = GetComponent<Rigidbody2D>();
}
void YourMovementFunction(){
if (!rg) return;
rg.AddForce(transform.forward * Time.deltaTime * forceGathered, ForceMode2D.Impulse);
}
I have a requirement that the bullets on a specific implementation of a scatterplot needs to have labels next to them, however, it is known that many of the datapoints in the set are identical or very close to one another, so if I were to set labels on a fixed coordinate relative to the bullet, the labels would stack on top of eachother and not be readable.
I want to implement this so that the labels will give way for eachother - moving around, so they don't overlap - and I am thinking that this is a common enough idea that some approach already exists, but I have no idea what to search for. Does this concept have a name?
I would ofcource appreciate an implementation example, but that is not the most important thing. I am sure I can solve it myself, but I'd rather not reinvent something that someone else has already done better.
The image above displays examples of bullets on top of and close to each other
I ended up finding inspiration in Simulated Annealing.
My solution looks like this
/**
* Implements an algorithm for placing labels on a chart in a way so that they
* do not overlap as much.
* The approach is inspired by Simulated Annealing
* (https://en.wikipedia.org/wiki/Simulated_annealing)
*/
export class Placer {
private knownPositions: Coordinate[];
private START_RADIUS = 20;
private RUNS = 15;
private ORIGIN_WEIGHT = 2;
constructor() {
this.knownPositions = []
}
/**
* Get a good spot to place the object.
*
* Given a start coordinate, this method tries to find the best place
* that is close to that point but not too close to other known points.
*
* #param {Coordinate} coordinate
* #returns {Coordinate}
*/
getPlacement(coordinate: Coordinate) : Coordinate {
let radius = this.START_RADIUS;
let lastPosition = coordinate;
let lastScore = 0;
while (radius > 0) {
const newPosition = this.getRandomPosition(coordinate, radius);
const newScore = this.getScore(newPosition, coordinate);
if (newScore > lastScore) {
lastPosition = newPosition;
lastScore = newScore;
}
radius -= this.START_RADIUS / this.RUNS;
}
this.knownPositions.push(lastPosition);
return lastPosition;
}
/**
* Return a random point on the radius around the position
*
* #param {Coordinate} position Center point
* #param {number} radius Distance from `position` to find a point
* #returns {Coordinate} A random point `radius` distance away from
* `position`
*/
private getRandomPosition(position: Coordinate, radius:number) : Coordinate {
const randomRotation = radians(Math.random() * 360);
const xOffset = Math.cos(randomRotation) * radius;
const yOffset = Math.sin(randomRotation) * radius;
return {
x: position.x + xOffset,
y: position.y + yOffset,
}
}
/**
* Returns a number score of a position. The further away it is from any
* other known point, the better the score (bigger number), however, it
* suffers a subtraction in score the further away it gets from its origin
* point.
*
* #param {Coordinate} position The position to score
* #param {Coordinate} origin The initial position before looking for
* better ones
* #returns {number} The representation of the score
*/
private getScore(position: Coordinate, origin: Coordinate) : number {
let closest: number = null;
this.knownPositions.forEach((knownPosition) => {
const distance = Math.abs(Math.sqrt(
Math.pow(knownPosition.x - position.x, 2) +
Math.pow(knownPosition.y - position.y, 2)
));
if (closest === null || distance < closest) {
closest = distance;
}
});
const distancetoOrigin = Math.abs(Math.sqrt(
Math.pow(origin.x - position.x, 2) +
Math.pow(origin.y - position.y, 2)
));
return closest - (distancetoOrigin / this.ORIGIN_WEIGHT);
}
}
There is room for improvement in the getScore method, but the results are good enough for my case.
Basically, all points try to move to a random position in a given radius and sees if that position is "better" than the original. The algorithm keeps doing that for a smaller and smaller radius until radius = 0.
The class keeps track of all known points, so that when you try to place point number two, the scoring can account for the presence of point number one.
For my current project it is necessary, that I compute the screen coordinates of a given point in the world space in Unity.
I used this tutorial to write a methode to do so.
After some debugging the x and y screen coordinate are correct, but my z coordinates looks wrong and I have some more questions:
static public Vector3 convertWorldToScreenCoordinates (Vector3 point, PhotoData photoData)
{
// get the camera
Camera camera = GameObject.Find (photoData.cameraName).camera;
/*
* 1 convert P_world to P_camera
*/
Vector4 pointInCameraCoodinates = convertWorldToCameraCoordinates (point, photoData);
/*
* 2 convert P_camera to P_clipped
*/
Vector4 pointInClipCoordinates = camera.projectionMatrix * pointInCameraCoodinates;
/*
* 3 convert P_clipped to P_ndc
* Normalized Device Coordinates
*/
Vector3 pointInNdc = pointInClipCoordinates / pointInClipCoordinates.w;
/*
* 4 convert P_ndc to P_screen
*/
Vector3 pointInScreenCoordinates;
pointInScreenCoordinates.x = camera.pixelWidth / 2.0f * (pointInNdc.x + 1);
pointInScreenCoordinates.y = camera.pixelHeight / 2.0f * (pointInNdc.y + 1);
pointInScreenCoordinates.z = ((camera.farClipPlane - camera.nearClipPlane) * pointInNdc.z + (camera.farClipPlane + camera.nearClipPlane)) / 2.0f;
// return screencoordinates
return pointInScreenCoordinates;
}
PhotoData is a class, that contains some information about the camera. The important part here is that I can access the camera.
static public Vector4 convertWorldToCameraCoordinates (Vector3 point, PhotoData photoData)
{
// translate the point by the negative camera-offset
//and convert to Vector4
Vector4 translatedPoint = point - photoData.cameraPosition;
// by default translatedPoint.w is 0
translatedPoint.w = 1.0f;
// create transformation matrix
Matrix4x4 transformationMatrix = Matrix4x4.identity;
transformationMatrix.SetRow (0, photoData.camRight);
transformationMatrix.SetRow (1, photoData.camUp);
transformationMatrix.SetRow (2, - photoData.camForward);
Vector4 transformedPoint = transformationMatrix * translatedPoint;
return transformedPoint;
}
First of all, the tutorial mentions, that after computing the ndc-values, "the range of values is now normalized from -1 to 1 in all 3 axes". This is not true in my case and I do not see what I am doing wrong.
My second question is, does pointInClipCoordinates.z < 0 mean the world point is "behind" my camera?
And the last question so far is why do I have to use - photoData.camForward?
// edit: updated code + questions
For editor scripts, use HandleUtility.WorldToGUIPoint (available since Unity3D 4.12) to convert a world space point to a 2D GUI position.
So I have that panel or any other mxml component. I want somehow to rotate it around like a wheel of a car with which you drive it... loke a Racing wheel... sow like when mousebutton is down it captures pont of component... when you move mouse component rotates (not moves) according to new mouse position... How to rotate MXML component round its center like a wheel respectfully to mouse?
welll feel free to edit this question because I know Ive formulated it in a bad way...
Add these to a utility class if you don't want to add a dependency to fl.motion.*
/**
* Rotates a matrix about a point defined inside the matrix's transformation space.
* This can be used to rotate a movie clip around a transformation point inside itself.
*
* #param m A Matrix instance.
*
* #param x The x coordinate of the point.
*
* #param y The y coordinate of the point.
*
* #param angleDegrees The angle of rotation in degrees.
* #playerversion Flash 9.0.28.0
* #langversion 3.0
* #keyword Matrix, Copy Motion as ActionScript
* #see flash.geom.Matrix
*/
public static function rotateAroundInternalPoint(m:Matrix, x:Number, y:Number, angleDegrees:Number):void
{
var point:Point = new Point(x, y);
point = m.transformPoint(point);
m.tx -= point.x;
m.ty -= point.y;
m.rotate(angleDegrees*(Math.PI/180));
m.tx += point.x;
m.ty += point.y;
}
/**
* Rotates a matrix about a point defined outside the matrix's transformation space.
* This can be used to rotate a movie clip around a transformation point in its parent.
*
* #param m A Matrix instance.
*
* #param x The x coordinate of the point.
*
* #param y The y coordinate of the point.
*
* #param angleDegrees The angle of rotation in degrees.
* #playerversion Flash 9.0.28.0
* #langversion 3.0
* #keyword Matrix, Copy Motion as ActionScript
* #see flash.geom.Matrix
*/
public static function rotateAroundExternalPoint(m:Matrix, x:Number, y:Number, angleDegrees:Number):void
{
m.tx -= x;
m.ty -= y;
m.rotate(angleDegrees*(Math.PI/180));
m.tx += x;
m.ty += y;
}
They are MatrixTransformer's rotateAroundInternalPoint() and rotateAroundExternalPoint()
That would be for 2d. For 3d see transformAround.
Don't forget to check if layout siblings are updated properly or not.
HTH
I believe you can rotate the component using the rotateX, rotateY, and rotateZ properties:
http://docs.huihoo.com/flex/4/mx/core/UIComponent.html#rotationX
Just make that happen in response to a mouse click.
I am building a diagramming tool using Adobe Flex 3. I am about to implement connector lines and I have a question.
Imagine I have 2 squares at random positions on the canvas. I need to draw an arrowed connector line between them. I need it to tend to the target square's center but end on its border.
How do I find out the exact points between which to draw the line?
Thank you
Here is an example doing what you want.
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.ui.Mouse;
/**
* Sample class to draw squares and arrows between them.
*/
public class SquareArrows extends Sprite
{
/**
* Initialize the scene as soon as we can.
*/
public function SquareArrows()
{
if(stage) {
init();
}
else {
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
/**
* Draw two squares and an arrow between them.
*/
private function init(e : Event = null) : void
{
if(hasEventListener(Event.ADDED_TO_STAGE)) {
removeEventListener(Event.ADDED_TO_STAGE, init);
}
// Drawing random-sized squares.
var squareOne : Shape =
getSquareShape((Math.random() * 50) + 20, 0xBBBBBB);
var squareTwo : Shape =
getSquareShape((Math.random() * 50) + 20, 0xDDDDDD);
addChild(squareOne);
addChild(squareTwo);
// Draw the connector.
var connector : Shape = getConnectorShape(squareOne, squareTwo);
addChild(connector);
}
/**
* Draw a connector arrow between two square shapes.
*/
private function getConnectorShape(connectFrom : Shape, connectTo : Shape) : Shape
{
// Getting the center of the first square.
var centerFrom : Point = new Point();
centerFrom.x = connectFrom.x + (connectFrom.width / 2);
centerFrom.y = connectFrom.y + (connectFrom.height / 2);
// Getting the center of the second square.
var centerTo : Point = new Point();
centerTo.x = connectTo.x + (connectTo.width / 2);
centerTo.y = connectTo.y + (connectTo.height / 2);
// Getting the angle between those two.
var angleTo : Number =
Math.atan2(centerTo.x - centerFrom.x, centerTo.y - centerFrom.y);
var angleFrom : Number =
Math.atan2(centerFrom.x - centerTo.x, centerFrom.y - centerTo.y);
// Getting the points on both borders.
var pointFrom : Point = getSquareBorderPointAtAngle(connectFrom, angleTo);
var pointTo : Point = getSquareBorderPointAtAngle(connectTo, angleFrom);
// Calculating arrow edges.
var arrowSlope : Number = 30;
var arrowHeadLength : Number = 10;
var vector : Point =
new Point(-(pointTo.x - pointFrom.x), -(pointTo.y - pointFrom.y));
// First edge of the head...
var edgeOneMatrix : Matrix = new Matrix();
edgeOneMatrix.rotate(arrowSlope * Math.PI / 180);
var edgeOneVector : Point = edgeOneMatrix.transformPoint(vector);
edgeOneVector.normalize(arrowHeadLength);
var edgeOne : Point = new Point();
edgeOne.x = pointTo.x + edgeOneVector.x;
edgeOne.y = pointTo.y + edgeOneVector.y;
// And second edge of the head.
var edgeTwoMatrix : Matrix = new Matrix();
edgeTwoMatrix.rotate((0 - arrowSlope) * Math.PI / 180);
var edgeTwoVector : Point = edgeTwoMatrix.transformPoint(vector);
edgeTwoVector.normalize(arrowHeadLength);
var edgeTwo : Point = new Point();
edgeTwo.x = pointTo.x + edgeTwoVector.x;
edgeTwo.y = pointTo.y + edgeTwoVector.y;
// Drawing the arrow.
var arrow : Shape = new Shape();
with(arrow.graphics) {
lineStyle(2);
// Drawing the line.
moveTo(pointFrom.x, pointFrom.y);
lineTo(pointTo.x, pointTo.y);
// Drawing the arrow head.
lineTo(edgeOne.x, edgeOne.y);
moveTo(pointTo.x, pointTo.y);
lineTo(edgeTwo.x, edgeTwo.y);
}
return arrow;
}
/**
* Utility method to get a point on a square border at a certain angle.
*/
private function getSquareBorderPointAtAngle(square : Shape, angle : Number) : Point
{
// Calculating rays of inner and outer circles.
var minRay : Number = Math.SQRT2 * square.width / 2;
var maxRay : Number = square.width / 2;
// Calculating the weight of each rays depending on the angle.
var rayAtAngle : Number = ((maxRay - minRay) * Math.abs(Math.cos(angle * 2))) + minRay;
// We have our point.
var point : Point = new Point();
point.x = rayAtAngle * Math.sin(angle) + square.x + (square.width / 2);
point.y = rayAtAngle * Math.cos(angle) + square.y + (square.height / 2);
return point;
}
/**
* Utility method to draw a square of a given size in a new shape.
*/
private function getSquareShape(edgeSize : Number, fillColor : Number) : Shape
{
// Draw the square.
var square : Shape = new Shape();
with(square.graphics) {
lineStyle(1);
beginFill(fillColor);
drawRect(0, 0, edgeSize, edgeSize);
endFill();
}
// Set a random position.
square.x = Math.random() * (stage.stageWidth - square.width);
square.y = Math.random() * (stage.stageHeight - square.height);
return square;
}
}
}
This code isn't totally optimized. The idea is more to explain how it works. Basically, we are defining two (random) squares, and tracing a line between them. To trace the line, we calculate an angle from the center of the first square to the center of the second one, and we use a special method (getSquareBorderPointAtAngle) to extract a point on the square border in the right direction.
This method is the first key point of this snippet. We calculate that using simple circle geometry, with a little complexification on how we make the point match the border instead of matching a circle around or inside the square.
Then, we draw an arrow head. For that, we're making use of the Flash Matrix class, because it's much easier this way than to calculate it from the scratch.
And here we're done.
I was reading the answers here a month ago as I need the same thing. Found this connector drawing example in the meantime, and thought i'd share the link.
The example draws connector lines between uicomponents, and updates the lines as the connectors are dragged. Nice one!
(source: sammyjoeosborne.com)
http://sammyjoeosborne.com/Examples/Connector/ConnectorExample.html
the most simple thing is probably using flash.geom.Point. take both centers c1 and c2. take the vector d that is their difference. depending on its angle (315 to 45, 45 to 135, 135 to 225, 225 to 315) you will know which sides are involved (respectively: right and left, top and bottom, left and right, bottom and top).
then calculate intersections between each side and the line connecting the centers.
the line connecting the centers can be represented as p=t*v+c1 (speaking in vectors). represent the side as a line and then calculate t such that both equations yield the same point p, which is the intersection you are looking for.