List of usage examples for java.lang Math signum
public static float signum(float f)
From source file:net.pms.util.Rational.java
/** * Compares this {@link Rational} by value with any class implementing * {@link Number}.// w w w . ja v a2 s .c o m * <p> * This method is provided in preference to individual methods for each of * the six boolean comparison operators ({@literal <}, ==, {@literal >}, * {@literal >=}, !=, {@literal <=}). The suggested idiom for performing * these comparisons is: {@code (x.compareTo(y)} <<i>op</i>> * {@code 0)}, where <<i>op</i>> is one of the six comparison * operators. * <p> * <b>Note:</b> {@code NaN} can't be compared by value and is considered * greater than anything but itself as defined for {@link Double}. * * @param number the {@link Number} to which this {@link Rational}'s value * is to be compared. * @return A negative integer, zero, or a positive integer as this * {@link Rational} is numerically less than, equal to, or greater * than {@code number}. */ public int compareTo(@Nonnull Number number) { // Establish special cases boolean numberIsNaN; boolean numberIsInfinite; int numberSignum; if (number instanceof Rational) { numberIsNaN = Rational.isNaN((Rational) number); numberIsInfinite = Rational.isInfinite((Rational) number); numberSignum = ((Rational) number).numerator.signum(); } else if (number instanceof Float) { numberIsNaN = Float.isNaN(number.floatValue()); numberIsInfinite = Float.isInfinite(number.floatValue()); numberSignum = (int) Math.signum(number.floatValue()); } else if (number instanceof Double) { numberIsNaN = Double.isNaN(number.doubleValue()); numberIsInfinite = Double.isInfinite(number.doubleValue()); numberSignum = (int) Math.signum(number.doubleValue()); } else { numberIsNaN = false; numberIsInfinite = false; long l = number.longValue(); numberSignum = l == 0 ? 0 : l > 0 ? 1 : -1; } // NaN comparison is done according to the rules for Double. if (isNaN()) { return numberIsNaN ? 0 : 1; } if (numberIsNaN) { return -1; } if (isInfinite()) { if (numberIsInfinite) { return signum() - numberSignum; } return this.signum(); } if (numberIsInfinite) { return -numberSignum; } // List known integer types for faster and more accurate comparison if (number instanceof BigInteger) { if (isInteger()) { return bigIntegerValue().compareTo((BigInteger) number); } return bigDecimalValue(2, RoundingMode.HALF_EVEN).compareTo(new BigDecimal((BigInteger) number)); } if (number instanceof AtomicInteger || number instanceof AtomicLong || number instanceof Byte || number instanceof Integer || number instanceof Long || number instanceof Short) { if (isInteger()) { return bigIntegerValue().compareTo(BigInteger.valueOf(number.longValue())); } return bigDecimalValue(2, RoundingMode.HALF_EVEN).compareTo(new BigDecimal(number.longValue())); } if (number instanceof BigDecimal) { Rational other = valueOf((BigDecimal) number); return compareTo(other); } return bigDecimalValue().compareTo(new BigDecimal(number.doubleValue())); }
From source file:cc.flydev.launcher.Page.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (DISABLE_TOUCH_INTERACTION) { return false; }//from w w w . j a v a2s .c om super.onTouchEvent(ev); // Skip touch handling if there are no pages to swipe if (getChildCount() <= 0) return super.onTouchEvent(ev); acquireVelocityTrackerAndAddMovement(ev); final int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ if (!mScroller.isFinished()) { mScroller.abortAnimation(); } // Remember where the motion event started mDownMotionX = mLastMotionX = ev.getX(); mDownMotionY = mLastMotionY = ev.getY(); mDownScrollX = getScrollX(); float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = p[0]; mParentDownMotionY = p[1]; mLastMotionXRemainder = 0; mTotalMotionX = 0; mActivePointerId = ev.getPointerId(0); if (mTouchState == TOUCH_STATE_SCROLLING) { pageBeginMoving(); } break; case MotionEvent.ACTION_MOVE: if (mTouchState == TOUCH_STATE_SCROLLING) { // Scroll to follow the motion event final int pointerIndex = ev.findPointerIndex(mActivePointerId); if (pointerIndex == -1) return true; final float x = ev.getX(pointerIndex); final float deltaX = mLastMotionX + mLastMotionXRemainder - x; mTotalMotionX += Math.abs(deltaX); // Only scroll and update mLastMotionX if we have moved some discrete amount. We // keep the remainder because we are actually testing if we've moved from the last // scrolled position (which is discrete). if (Math.abs(deltaX) >= 1.0f) { mTouchX += deltaX; mSmoothingTime = System.nanoTime() / NANOTIME_DIV; if (!mDeferScrollUpdate) { scrollBy((int) deltaX, 0); if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX); } else { invalidate(); } mLastMotionX = x; mLastMotionXRemainder = deltaX - (int) deltaX; } else { awakenScrollBars(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); // Find the closest page to the touch point final int dragViewIndex = indexOfChild(mDragView); // Change the drag view if we are hovering over the drop target boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY); setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete); if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX); if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY); if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX); if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY); final int pageUnderPointIndex = getNearestHoverOverPageIndex(); if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView) && !isHoveringOverDelete) { mTempVisiblePagesRange[0] = 0; mTempVisiblePagesRange[1] = getPageCount() - 1; getOverviewModePages(mTempVisiblePagesRange); if (mTempVisiblePagesRange[0] <= pageUnderPointIndex && pageUnderPointIndex <= mTempVisiblePagesRange[1] && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) { mSidePageHoverIndex = pageUnderPointIndex; mSidePageHoverRunnable = new Runnable() { @Override public void run() { // Setup the scroll to the correct page before we swap the views snapToPage(pageUnderPointIndex); // For each of the pages between the paged view and the drag view, // animate them from the previous position to the new position in // the layout (as a result of the drag view moving in the layout) int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1; int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1 : pageUnderPointIndex; int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1 : pageUnderPointIndex; for (int i = lowerIndex; i <= upperIndex; ++i) { View v = getChildAt(i); // dragViewIndex < pageUnderPointIndex, so after we remove the // drag view all subsequent views to pageUnderPointIndex will // shift down. int oldX = getViewportOffsetX() + getChildOffset(i); int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta); // Animate the view translation from its old position to its new // position AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY); if (anim != null) { anim.cancel(); } v.setTranslationX(oldX - newX); anim = new AnimatorSet(); anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION); anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f)); anim.start(); v.setTag(anim); } removeView(mDragView); onRemoveView(mDragView, false); addView(mDragView, pageUnderPointIndex); onAddView(mDragView, pageUnderPointIndex); mSidePageHoverIndex = -1; mPageIndicator.setActiveMarker(getNextPage()); } }; postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT); } } else { removeCallbacks(mSidePageHoverRunnable); mSidePageHoverIndex = -1; } } else { determineScrollingStart(ev); } break; case MotionEvent.ACTION_UP: if (mTouchState == TOUCH_STATE_SCROLLING) { final int activePointerId = mActivePointerId; final int pointerIndex = ev.findPointerIndex(activePointerId); final float x = ev.getX(pointerIndex); final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocityX = (int) velocityTracker.getXVelocity(activePointerId); final int deltaX = (int) (x - mDownMotionX); final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth(); boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD; mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x); boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING && Math.abs(velocityX) > mFlingThresholdVelocity; if (!mFreeScroll) { // In the case that the page is moved far to one direction and then is flung // in the opposite direction, we use a threshold to determine whether we should // just return to the starting page, or if we should skip one further. boolean returnToOriginalPage = false; if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD && Math.signum(velocityX) != Math.signum(deltaX) && isFling) { returnToOriginalPage = true; } int finalPage; // We give flings precedence over large moves, which is why we short-circuit our // test for a large move if a fling has been registered. That is, a large // move to the left and fling to the right will register as a fling to the right. final boolean isRtl = isLayoutRtl(); boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0; boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0; if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft)) && mCurrentPage > 0) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1; snapToPageWithVelocity(finalPage, velocityX); } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft)) && mCurrentPage < getChildCount() - 1) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1; snapToPageWithVelocity(finalPage, velocityX); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_PREV_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so // we can just page int nextPage = Math.max(0, mCurrentPage - 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } float scaleX = getScaleX(); int vX = (int) (-velocityX * scaleX); int initialScrollX = (int) (getScrollX() * scaleX); mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0); invalidate(); } } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so // we can just page int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); boolean handledFling = false; if (!DISABLE_FLING_TO_DELETE) { // Check the velocity and see if we are flinging-to-delete PointF flingToDeleteVector = isFlingingToDelete(); if (flingToDeleteVector != null) { onFlingToDelete(flingToDeleteVector); handledFling = true; } } if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) { onDropToDelete(); } } else { if (!mCancelTap) { onUnhandledTap(ev); } } // Remove the callback to wait for the side page hover timeout removeCallbacks(mSidePageHoverRunnable); // End any intermediate reordering states resetTouchState(); break; case MotionEvent.ACTION_CANCEL: if (mTouchState == TOUCH_STATE_SCROLLING) { snapToDestination(); } resetTouchState(); break; case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); releaseVelocityTracker(); break; } return true; }
From source file:com.n2hsu.launcher.Page.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (DISABLE_TOUCH_INTERACTION) { return false; }//from www . j a v a2s. co m super.onTouchEvent(ev); // Skip touch handling if there are no pages to swipe if (getChildCount() <= 0) return super.onTouchEvent(ev); acquireVelocityTrackerAndAddMovement(ev); final int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ if (!mScroller.isFinished()) { mScroller.abortAnimation(); } // Remember where the motion event started mDownMotionX = mLastMotionX = ev.getX(); mDownMotionY = mLastMotionY = ev.getY(); mDownScrollX = getScrollX(); float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = p[0]; mParentDownMotionY = p[1]; mLastMotionXRemainder = 0; mTotalMotionX = 0; mActivePointerId = ev.getPointerId(0); if (mTouchState == TOUCH_STATE_SCROLLING) { pageBeginMoving(); } break; case MotionEvent.ACTION_MOVE: if (mTouchState == TOUCH_STATE_SCROLLING) { // Scroll to follow the motion event final int pointerIndex = ev.findPointerIndex(mActivePointerId); if (pointerIndex == -1) return true; final float x = ev.getX(pointerIndex); final float deltaX = mLastMotionX + mLastMotionXRemainder - x; mTotalMotionX += Math.abs(deltaX); // Only scroll and update mLastMotionX if we have moved some // discrete amount. We // keep the remainder because we are actually testing if we've // moved from the last // scrolled position (which is discrete). if (Math.abs(deltaX) >= 1.0f) { mTouchX += deltaX; mSmoothingTime = System.nanoTime() / NANOTIME_DIV; if (!mDeferScrollUpdate) { scrollBy((int) deltaX, 0); if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX); } else { invalidate(); } mLastMotionX = x; mLastMotionXRemainder = deltaX - (int) deltaX; } else { awakenScrollBars(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this // new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); // Find the closest page to the touch point final int dragViewIndex = indexOfChild(mDragView); // Change the drag view if we are hovering over the drop target boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY); setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete); if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX); if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY); if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX); if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY); final int pageUnderPointIndex = getNearestHoverOverPageIndex(); if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView) && !isHoveringOverDelete) { mTempVisiblePagesRange[0] = 0; mTempVisiblePagesRange[1] = getPageCount() - 1; getOverviewModePages(mTempVisiblePagesRange); if (mTempVisiblePagesRange[0] <= pageUnderPointIndex && pageUnderPointIndex <= mTempVisiblePagesRange[1] && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) { mSidePageHoverIndex = pageUnderPointIndex; mSidePageHoverRunnable = new Runnable() { @Override public void run() { // Setup the scroll to the correct page before // we swap the views snapToPage(pageUnderPointIndex); // For each of the pages between the paged view // and the drag view, // animate them from the previous position to // the new position in // the layout (as a result of the drag view // moving in the layout) int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1; int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1 : pageUnderPointIndex; int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1 : pageUnderPointIndex; for (int i = lowerIndex; i <= upperIndex; ++i) { View v = getChildAt(i); // dragViewIndex < pageUnderPointIndex, so // after we remove the // drag view all subsequent views to // pageUnderPointIndex will // shift down. int oldX = getViewportOffsetX() + getChildOffset(i); int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta); // Animate the view translation from its old // position to its new // position AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY); if (anim != null) { anim.cancel(); } v.setTranslationX(oldX - newX); anim = new AnimatorSet(); anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION); anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f)); anim.start(); v.setTag(anim); } removeView(mDragView); onRemoveView(mDragView, false); addView(mDragView, pageUnderPointIndex); onAddView(mDragView, pageUnderPointIndex); mSidePageHoverIndex = -1; mPageIndicator.setActiveMarker(getNextPage()); } }; postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT); } } else { removeCallbacks(mSidePageHoverRunnable); mSidePageHoverIndex = -1; } } else { determineScrollingStart(ev); } break; case MotionEvent.ACTION_UP: if (mTouchState == TOUCH_STATE_SCROLLING) { final int activePointerId = mActivePointerId; final int pointerIndex = ev.findPointerIndex(activePointerId); final float x = ev.getX(pointerIndex); final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocityX = (int) velocityTracker.getXVelocity(activePointerId); final int deltaX = (int) (x - mDownMotionX); final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth(); boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD; mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x); boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING && Math.abs(velocityX) > mFlingThresholdVelocity; if (!mFreeScroll) { // In the case that the page is moved far to one direction // and then is flung // in the opposite direction, we use a threshold to // determine whether we should // just return to the starting page, or if we should skip // one further. boolean returnToOriginalPage = false; if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD && Math.signum(velocityX) != Math.signum(deltaX) && isFling) { returnToOriginalPage = true; } int finalPage; // We give flings precedence over large moves, which is why // we short-circuit our // test for a large move if a fling has been registered. // That is, a large // move to the left and fling to the right will register as // a fling to the right. final boolean isRtl = isLayoutRtl(); boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0; boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0; if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft)) && mCurrentPage > 0) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1; snapToPageWithVelocity(finalPage, velocityX); } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft)) && mCurrentPage < getChildCount() - 1) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1; snapToPageWithVelocity(finalPage, velocityX); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_PREV_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), // so // we can just page int nextPage = Math.max(0, mCurrentPage - 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } float scaleX = getScaleX(); int vX = (int) (-velocityX * scaleX); int initialScrollX = (int) (getScrollX() * scaleX); mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0); invalidate(); } } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so // we can just page int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this // new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); boolean handledFling = false; if (!DISABLE_FLING_TO_DELETE) { // Check the velocity and see if we are flinging-to-delete PointF flingToDeleteVector = isFlingingToDelete(); if (flingToDeleteVector != null) { onFlingToDelete(flingToDeleteVector); handledFling = true; } } if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) { onDropToDelete(); } } else { if (!mCancelTap) { onUnhandledTap(ev); } } // Remove the callback to wait for the side page hover timeout removeCallbacks(mSidePageHoverRunnable); // End any intermediate reordering states resetTouchState(); break; case MotionEvent.ACTION_CANCEL: if (mTouchState == TOUCH_STATE_SCROLLING) { snapToDestination(); } resetTouchState(); break; case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); releaseVelocityTracker(); break; } return true; }
From source file:com.android.leanlauncher.CellLayout.java
private void computeDirectionVector(float deltaX, float deltaY, int[] result) { double angle = Math.atan(deltaY / deltaX); result[0] = 0;/*from ww w .ja va 2s . c o m*/ result[1] = 0; if (Math.abs(Math.cos(angle)) > 0.5f) { result[0] = (int) Math.signum(deltaX); } if (Math.abs(Math.sin(angle)) > 0.5f) { result[1] = (int) Math.signum(deltaY); } }
From source file:com.android.launcher3.CellLayout.java
private void computeDirectionVector(float deltaX, float deltaY, int[] result) { double angle = Math.atan(((float) deltaY) / deltaX); result[0] = 0;/*from w w w . j av a 2 s . co m*/ result[1] = 0; if (Math.abs(Math.cos(angle)) > 0.5f) { result[0] = (int) Math.signum(deltaX); } if (Math.abs(Math.sin(angle)) > 0.5f) { result[1] = (int) Math.signum(deltaY); } }
From source file:com.breakout.main.GameState.java
/** * Tests for a collision with the rectangles in mPossibleCollisions as the ball travels from * (curX,curY).// w w w . java 2 s . c om * <p> * We can't return multiple values from a method call in Java. We don't want to allocate * storage for the return value on each frame (this being part of the main game loop). We * can define a class that holds all of the return values and allocate a single instance * of it when GameState is constructed, or just drop the values into dedicated return-value * fields. The latter is incrementally easier, so we return the object we hit, and store * additional details in these fields: * <ul> * <li>mHitDistanceLeft - the amount of distance remaining to travel after impact * <li>mHitFace - what face orientation we hit * <li>mHitXAdj, mHitYAdj - position adjustment so objects won't intersect * </ul> * * @param rects Array of rects to test against. * @param numRects Number of rects in array. * @param curX Current X position. * @param curY Current Y position. * @param dirX X component of normalized direction vector. * @param dirY Y component of normalized direction vector. * @param distance Distance to travel. * @param radius Radius of the ball. * @return The object we struck, or null if none. */ private BaseRect findFirstCollision(BaseRect[] rects, final int numRects, final float curX, final float curY, final float dirX, final float dirY, final float distance, final float radius) { /* * The "coarse" function has indicated that a collision is possible. We need to get * an exact determination of what we're hitting. * * We can either use some math to compute the time of intersection of each rect with * the moving ball (a "sweeping" collision test, perhaps even straying into * "continuous collision detection"), or we can just step the ball forward until * it collides with something or reaches the end point. The latter isn't as precise, * but is much simpler, so we'll do that. * * We can use a test similar to the Separating Axis Theorem, but with a circle vs. * rectangle collision it's possible for the axis-aligned projections to overlap but * not have a collision (e.g. the circle is near one corner). We need to perform an * additional test to check the distance from the closest vertex to the center of the * circle. The fancy way to figure out which corner is closest is with Voronoi regions, * but we don't really need that: since we're colliding with axis-aligned rects, we can * just collapse the whole thing into a single quadrant. * * Nice illustration here: * http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection * * Once we determine that a collision has occurred, we need to determine where we hit * so that we can decide how to bounce. For our bricks we're either hitting a vertical * or horizontal surface; these will cause us to invert the X component or Y component * of our direction vector. It also makes sense visually to reverse direction when * you run into a corner. * * It's possible to get "tunneling" effects, which may look weird but are actually * legitimate. Two common scenarios: * * (1) Suppose the ball is moving upward and slightly to the left. If it * squeezes between the gap in the bricks and hits a right edge, it will * do a vertical-surface bounce (i.e. start moving back to the right), and * almost immediately hit the vertical surface of the brick to the right. * With the right angle, this can repeat in a nearby column and climb up through * several layers. (Unless the ball is small relative to the gap between bricks, * this is hard to do in practice.) * (2) A "sharp corner" bounce can keep the ball moving upward. For * example, a ball moving up and right hits the bottom of a brick, * and heads down and to the right. It hits the top-left corner of * a brick, and reverses direction (up and left). It hits the bottom * of another brick, and while moving down and left it hits the * top-right corner of a fourth brick. If the angle is right, this * pattern will continue, knocking out a vertical tunnel. Because it's * hitting on corners, this is easy to do even if the horizontal gap * between bricks is fairly narrow. * * The smaller the inter-brick gap is, the less likely the tunneling * effects are to occur. With a small enough gap (and a reasonable MAX_STEP) * it's impossible to hit an "inside" corner or surface. * * It's possible to collide with two shapes at once. We ignore this situation. * Whichever object we happen to examine first gets credit. */ // Maximum distance, in arena coordinates, we advance the ball on each iteration of // the loop. If this is too small, we'll do a lot of unnecessary iterations. If it's // too large (e.g. more than the ball's radius), the ball can end up inside an object, // or pass through one entirely. final float MAX_STEP = 2.0f; // Minimum distance. After a collision the objects are just barely in contact, so at // each step we need to move a little or we'll double-collide. The minimum exists to // ensure that we don't get hosed by floating point round-off error. final float MIN_STEP = 0.001f; float radiusSq = radius * radius; int faceHit = HIT_FACE_NONE; int faceToAdjust = HIT_FACE_NONE; float traveled = 0.0f; while (traveled < distance) { // Travel a bit. if (distance - traveled > MAX_STEP) { traveled += MAX_STEP; } else if (distance - traveled < MIN_STEP) { //Log.d(TAG, "WOW: skipping tiny step distance " + (distance - traveled)); break; } else { traveled = distance; } float circleXWorld = curX + dirX * traveled; float circleYWorld = curY + dirY * traveled; for (int i = 0; i < numRects; i++) { BaseRect rect = rects[i]; float rectXWorld = rect.getXPosition(); float rectYWorld = rect.getYPosition(); float rectXScaleHalf = rect.getXScale() / 2.0f; float rectYScaleHalf = rect.getYScale() / 2.0f; // Translate the circle so that it's in the first quadrant, with the center of the // rectangle at (0,0). float circleX = Math.abs(circleXWorld - rectXWorld); float circleY = Math.abs(circleYWorld - rectYWorld); if (circleX > rectXScaleHalf + radius || circleY > rectYScaleHalf + radius) { // Circle is too far from rect edge(s) to overlap. No collision. continue; } /* * Check to see if the center of the circle is inside the rect on one axis. The * previous test eliminated anything that was too far on either axis, so * if this passes then we must have a collision. * * We're not moving the ball fast enough (limited by MAX_STEP) to get the center * of the ball completely inside the rect (i.e. we shouldn't see a case where the * center is inside the rect on *both* axes), so if we're inside in the X axis we * can conclude that we just collided due to vertical motion, and have hit a * horizontal surface. * * If the center isn't inside on either axis, we've hit the corner case, and * need to do a distance test. */ if (circleX <= rectXScaleHalf) { faceToAdjust = faceHit = HIT_FACE_HORIZONTAL; } else if (circleY <= rectYScaleHalf) { faceToAdjust = faceHit = HIT_FACE_VERTICAL; } else { // Check the distance from rect corner to center of circle. float xdist = circleX - rectXScaleHalf; float ydist = circleY - rectYScaleHalf; if (xdist * xdist + ydist * ydist > radiusSq) { // Not close enough. //Log.d(TAG, "COL: corner miss"); continue; } /* * The center point of the ball is outside both edges of the rectangle, * but the corner is inside the radius of the circle, so this is a corner * hit. We need to decide how to bounce off. * * One approach is to see which edge is closest. We know we're within a * ball-radius of both edges. If you imagine a ball moving straight upward, * hitting just to the left of the bottom-left corner of a brick, you'll * note that the impact occurs when the X distance (from brick edge to * center of ball) is very small, and the Y distance is close to the ball * radius. So if X < Y, it's a horizontal-surface hit. * * However, there's a nasty edge case: imagine the ball is traveling up and * to the right. It skims past the top-left corner of a brick. If the ball * is positioned just barely outside the collision radius to the left of the * brick in the current frame, our next step could take us to the other side * of the ball -- at which point we "collide" with the horizontal *top* * surface of the brick. The brick is destroyed and the ball "bounces" down * and to the right (because we reverse Y direction on a horizontal hit). * Decreasing MAX_STEP makes this less likely, but we can't make it impossible. * * Another approach is to compare the direction the ball was moving with * which corner we hit. Consider the bottom-left corner of a brick. There * are three ways to hit it: straight in (ball moving up and right), skimming * from the left (ball moving down and right), and skimming from below * (ball moving up and left). By comparing just the sign of the components * of the ball's direction vector with the sign of a vector drawn from the * corner to the center of the rect, we can decide what sort of impact * we've had. * * If the signs match, it's a "sharp" corner impact, and we want to bounce * straight back. If only X matches, we're approaching from the side, and * it's a vertical side impact. If only Y matches, we're approaching from * the bottom, and it's a horizontal impact. The collision behavior no * longer depends on which side we're actually touching, concealing the * fact that the ball has effectively passed through the corner of the brick * and we're catching the collision a bit late. * * If bouncing straight back off of a corner is undesirable, we can just * use the computation done in the faceToAdjust assignment for "sharp * "corner" impacts instead. */ float dirXSign = Math.signum(dirX); float dirYSign = Math.signum(dirY); float cornerXSign = Math.signum(rectXWorld - circleXWorld); float cornerYSign = Math.signum(rectYWorld - circleYWorld); if (dirXSign == cornerXSign && dirYSign == cornerYSign) { faceHit = HIT_FACE_SHARPCORNER; } else if (dirXSign == cornerXSign) { faceHit = HIT_FACE_VERTICAL; } else if (dirYSign == cornerYSign) { faceHit = HIT_FACE_HORIZONTAL; } else { // This would mean we hit the far corner of the brick, i.e. the ball // passed completely through it. faceHit = HIT_FACE_SHARPCORNER; } // Adjust whichever requires the least movement to guarantee we're no // longer colliding. if (xdist < ydist) { faceToAdjust = HIT_FACE_HORIZONTAL; } else { faceToAdjust = HIT_FACE_VERTICAL; } } /* * Collision! * * Because we're moving in discrete steps rather than continuously, we will * usually end up slightly embedded in the object. If, after reversing direction, * we subsequently step forward very slightly (assuming a non-destructable * object like a wall), we will detect a second collision with the same object, * and reverse direction back *into* the wall. Visually, the ball will "stick" * to the wall and vibrate. * * We need to back the ball out slightly. Ideally we'd back it along the path * the ball was traveling by just the right amount, but unless MAX_STEP is * really large the difference between that and a minimum-distance axis-aligned * shift is negligible -- and this is easier to compute. * * There's some risk that our adjustment will leave the ball trapped in a * different object. Since the ball is the only object that's moving, and the * direction of adjustment shouldn't be too far from the angle of incidence, we * shouldn't have this problem in practice. * * Note this leaves the ball just *barely* in contact with the object it hit, * which means it's technically still colliding. This won't cause us to * collide again and reverse course back into the object because we will move * the ball a nonzero distance away from the object before we check for another * collision. The use of MIN_STEP ensures that we won't fall victim to floating * point round-off error. (If we didn't want to guarantee movement, we could * shift the ball a tiny bit farther so that it simply wasn't in contact.) */ float hitXAdj, hitYAdj; if (faceToAdjust == HIT_FACE_HORIZONTAL) { hitXAdj = 0.0f; hitYAdj = rectYScaleHalf + radius - circleY; if (circleYWorld < rectYWorld) { // ball is below rect, must be moving up, so adjust it down hitYAdj = -hitYAdj; } } else if (faceToAdjust == HIT_FACE_VERTICAL) { hitXAdj = rectXScaleHalf + radius - circleX; hitYAdj = 0.0f; if (circleXWorld < rectXWorld) { // ball is left of rect, must be moving to right, so adjust it left hitXAdj = -hitXAdj; } } else { hitXAdj = hitYAdj = 0.0f; } mHitFace = faceHit; mHitDistanceTraveled = traveled; mHitXAdj = hitXAdj; mHitYAdj = hitYAdj; return rect; } } //Log.d(TAG, "COL: no collision"); return null; }
From source file:com.wb.launcher3.Page.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (DISABLE_TOUCH_INTERACTION) { return false; }/*from w ww . j a va 2 s.c om*/ super.onTouchEvent(ev); // Skip touch handling if there are no pages to swipe if (getChildCount() <= 0) return super.onTouchEvent(ev); acquireVelocityTrackerAndAddMovement(ev); final int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ if (!mScroller.isFinished()) { mScroller.abortAnimation(); } // Remember where the motion event started mDownMotionX = mLastMotionX = ev.getX(); mDownMotionY = mLastMotionY = ev.getY(); mDownScrollX = getScrollX(); float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = p[0]; mParentDownMotionY = p[1]; mLastMotionXRemainder = 0; mTotalMotionX = 0; mActivePointerId = ev.getPointerId(0); if (mTouchState == TOUCH_STATE_SCROLLING) { pageBeginMoving(); } break; case MotionEvent.ACTION_MOVE: //*/zhangwuba add 2014-5-8 if (getLauncherDeleteAppSate()) { return true; } //*/ if (mTouchState == TOUCH_STATE_SCROLLING) { // Scroll to follow the motion event final int pointerIndex = ev.findPointerIndex(mActivePointerId); if (pointerIndex == -1) return true; final float x = ev.getX(pointerIndex); final float deltaX = mLastMotionX + mLastMotionXRemainder - x; mTotalMotionX += Math.abs(deltaX); // Only scroll and update mLastMotionX if we have moved some discrete amount. We // keep the remainder because we are actually testing if we've moved from the last // scrolled position (which is discrete). if (Math.abs(deltaX) >= 1.0f) { mTouchX += deltaX; mSmoothingTime = System.nanoTime() / NANOTIME_DIV; if (!mDeferScrollUpdate) { scrollBy((int) deltaX, 0); if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX); } else { invalidate(); } mLastMotionX = x; mLastMotionXRemainder = deltaX - (int) deltaX; } else { awakenScrollBars(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); // Find the closest page to the touch point final int dragViewIndex = indexOfChild(mDragView); // Change the drag view if we are hovering over the drop target boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY); setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete); if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX); if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY); if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX); if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY); final int pageUnderPointIndex = getNearestHoverOverPageIndex(); if (pageUnderPointIndex > -1 && pageUnderPointIndex != indexOfChild(mDragView) && !isHoveringOverDelete) { mTempVisiblePagesRange[0] = 0; mTempVisiblePagesRange[1] = getPageCount() - 1; getOverviewModePages(mTempVisiblePagesRange); if (mTempVisiblePagesRange[0] <= pageUnderPointIndex && pageUnderPointIndex <= mTempVisiblePagesRange[1] && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) { mSidePageHoverIndex = pageUnderPointIndex; mSidePageHoverRunnable = new Runnable() { @Override public void run() { // Setup the scroll to the correct page before we swap the views snapToPage(pageUnderPointIndex); // For each of the pages between the paged view and the drag view, // animate them from the previous position to the new position in // the layout (as a result of the drag view moving in the layout) int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1; int lowerIndex = (dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1 : pageUnderPointIndex; int upperIndex = (dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1 : pageUnderPointIndex; for (int i = lowerIndex; i <= upperIndex; ++i) { View v = getChildAt(i); // dragViewIndex < pageUnderPointIndex, so after we remove the // drag view all subsequent views to pageUnderPointIndex will // shift down. int oldX = getViewportOffsetX() + getChildOffset(i); int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta); // Animate the view translation from its old position to its new // position AnimatorSet anim = (AnimatorSet) v.getTag(ANIM_TAG_KEY); if (anim != null) { anim.cancel(); } v.setTranslationX(oldX - newX); anim = new AnimatorSet(); anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION); anim.playTogether(ObjectAnimator.ofFloat(v, "translationX", 0f)); anim.start(); v.setTag(anim); } removeView(mDragView); onRemoveView(mDragView, false); addView(mDragView, pageUnderPointIndex); onAddView(mDragView, pageUnderPointIndex); mSidePageHoverIndex = -1; mPageIndicator.setActiveMarker(getNextPage()); } }; postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT); } } else { removeCallbacks(mSidePageHoverRunnable); mSidePageHoverIndex = -1; } } else { determineScrollingStart(ev); } break; case MotionEvent.ACTION_UP: if (mTouchState == TOUCH_STATE_SCROLLING) { final int activePointerId = mActivePointerId; final int pointerIndex = ev.findPointerIndex(activePointerId); final float x = ev.getX(pointerIndex); final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocityX = (int) velocityTracker.getXVelocity(activePointerId); final int deltaX = (int) (x - mDownMotionX); final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth(); boolean isSignificantMove = Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD; mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x); boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING && Math.abs(velocityX) > mFlingThresholdVelocity; if (!mFreeScroll) { // In the case that the page is moved far to one direction and then is flung // in the opposite direction, we use a threshold to determine whether we should // just return to the starting page, or if we should skip one further. boolean returnToOriginalPage = false; if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD && Math.signum(velocityX) != Math.signum(deltaX) && isFling) { returnToOriginalPage = true; } //*/Added by tyd Greg 2014-03-20,for transition effect if (TydtechConfig.CYCLE_ROLL_PAGES_ENABLED) { m_moveNextDeltaX = deltaX; m_isSignificantMoveNext = (!returnToOriginalPage && (isSignificantMove || isFling)); } //*/ int finalPage; // We give flings precedence over large moves, which is why we short-circuit our // test for a large move if a fling has been registered. That is, a large // move to the left and fling to the right will register as a fling to the right. final boolean isRtl = isLayoutRtl(); boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0; boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0; if (((isSignificantMove && !isDeltaXLeft && !isFling) || (isFling && !isVelocityXLeft)) && mCurrentPage > 0) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1; snapToPageWithVelocity(finalPage, velocityX); } else if (((isSignificantMove && isDeltaXLeft && !isFling) || (isFling && isVelocityXLeft)) && mCurrentPage < getChildCount() - 1) { finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1; snapToPageWithVelocity(finalPage, velocityX); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_PREV_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so // we can just page int nextPage = Math.max(0, mCurrentPage - 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } float scaleX = getScaleX(); int vX = (int) (-velocityX * scaleX); int initialScrollX = (int) (getScrollX() * scaleX); mScroller.fling(initialScrollX, getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0); invalidate(); } } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) { // at this point we have not moved beyond the touch slop // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so // we can just page int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1); if (nextPage != mCurrentPage) { snapToPage(nextPage); } else { snapToDestination(); } } else if (mTouchState == TOUCH_STATE_REORDERING) { // Update the last motion position mLastMotionX = ev.getX(); mLastMotionY = ev.getY(); // Update the parent down so that our zoom animations take this new movement into // account float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); mParentDownMotionX = pt[0]; mParentDownMotionY = pt[1]; updateDragViewTranslationDuringDrag(); boolean handledFling = false; if (!DISABLE_FLING_TO_DELETE) { // Check the velocity and see if we are flinging-to-delete PointF flingToDeleteVector = isFlingingToDelete(); if (flingToDeleteVector != null) { onFlingToDelete(flingToDeleteVector); handledFling = true; } } if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX, (int) mParentDownMotionY)) { onDropToDelete(); } } //*/Added by tyd Greg 2014-03-21,for support the touch swipe gesture else if (mTouchState == TOUCH_SWIPE_DOWN_GESTURE) { if (mOnTouchSwipeGestureListener != null) { mOnTouchSwipeGestureListener.fireSwipeDownAction(); } } else if (mTouchState == TOUCH_SWIPE_UP_GESTURE) { if (mOnTouchSwipeGestureListener != null) { mOnTouchSwipeGestureListener.fireSwipeUpAction(); } } //*/ else { if (!mCancelTap) { onUnhandledTap(ev); } } // Remove the callback to wait for the side page hover timeout removeCallbacks(mSidePageHoverRunnable); // End any intermediate reordering states resetTouchState(); break; case MotionEvent.ACTION_CANCEL: if (mTouchState == TOUCH_STATE_SCROLLING) { snapToDestination(); } resetTouchState(); break; case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); releaseVelocityTracker(); break; } return true; }
From source file:jmri.enginedriver.throttle.java
int speedChange(int whichThrottle, int change) { SeekBar throttle_slider = getThrottleSlider(whichThrottle); double displayUnitScale = getDisplayUnitScale(whichThrottle); int lastSpeed = throttle_slider.getProgress(); int lastScaleSpeed = (int) Math.round(lastSpeed * displayUnitScale); int scaleSpeed = lastScaleSpeed + change; int speed = (int) Math.round(scaleSpeed / displayUnitScale); if (lastScaleSpeed == scaleSpeed) { speed += Math.signum(change); }//w ww. jav a 2 s . c om if (speed < 0) //insure speed is inside bounds speed = 0; if (speed > MAX_SPEED_VAL_WIT) speed = MAX_SPEED_VAL_WIT; throttle_slider.setProgress(speed); return speed; }
From source file:com.serenegiant.autoparrot.BaseAutoPilotFragment.java
private int cameraExposureToProgress(final float exposure) { return (int) (Math.signum(exposure) * (Math.sqrt(Math.abs(exposure * 1500000)))) + 1500; }
From source file:com.serenegiant.autoparrot.BaseAutoPilotFragment.java
private float progressToCameraExposure(final int progress) { final int p = progress - 1500; return Math.signum(p) * (p * p / 1500000.0f); }