Pages

Showing posts with label Computer. Show all posts
Showing posts with label Computer. Show all posts

Curl Page - harism modify left to right

I have modify code from harism to fit my requirement curl page from left to right like read arabic book. thanks to harism, its cool...
package fi.harism.curl; 

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.PointF; 
import android.graphics.RectF; 
import android.opengl.GLSurfaceView; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 

@SuppressLint("FloatMath") 
public class CurlView extends GLSurfaceView implements
        View.OnTouchListener, CurlRenderer.Observer { 

    // Curl state. We are flipping none, left or right page. 
    private static final int CURL_LEFT = 1;
    private static final int CURL_NONE = 0;
    private static final int CURL_RIGHT = 2;

    // Constants for mAnimationTargetEvent. 
    private static final int SET_CURL_TO_LEFT = 1;
    private static final int SET_CURL_TO_RIGHT = 2;

    // Shows one page at the center of view. 
    public static final int SHOW_ONE_PAGE = 1;
    // Shows two pages side by side. 
    public static final int SHOW_TWO_PAGES = 2;

    private boolean mAllowLastPageCurl = true;

    private boolean mAnimate = false;
    private long mAnimationDurationTime = 300;
    private PointF mAnimationSource = new PointF();
    private long mAnimationStartTime;
    private PointF mAnimationTarget = new PointF();
    private int mAnimationTargetEvent;

    private PointF mCurlDir = new PointF();

    private PointF mCurlPos = new PointF();
    private int mCurlState = CURL_NONE;
    // Current bitmap index. This is always showed as front of right page. 
    private int mCurrentIndex = 0;

    // Start position for dragging. 
    private PointF mDragStartPos = new PointF();

    private boolean mEnableTouchPressure = false;
    // Bitmap size. These are updated from renderer once it's initialized. 
    private int mPageBitmapHeight = -1; 

    private int mPageBitmapWidth = -1; 
    // Page meshes. Left and right meshes are 'static' while curl is used to
    // show page flipping. 
    private CurlMesh mPageCurl; 

    private CurlMesh mPageLeft; 
    private PageProvider mPageProvider; 
    private CurlMesh mPageRight; 

    private PointerPosition mPointerPos = new PointerPosition();

    private CurlRenderer mRenderer; 
    private boolean mRenderLeftPage = true;
    private SizeChangedObserver mSizeChangedObserver; 

    // One page is the default. 
    private int mViewMode = SHOW_ONE_PAGE;
     
    private boolean RIGHT_TO_LEFT = true;

    /** 
     * Default constructor. 
     */ 
    public CurlView(Context ctx) { 
        super(ctx); 
        init(ctx); 
    } 

    /** 
     * Default constructor. 
     */ 
    public CurlView(Context ctx, AttributeSet attrs) {
        super(ctx, attrs); 
        init(ctx); 
    } 

    /** 
     * Default constructor. 
     */ 
    public CurlView(Context ctx, AttributeSet attrs, int defStyle) {
        this(ctx, attrs); 
    } 

    /** 
     * Get current page index. Page indices are zero based values presenting 
     * page being shown on right side of the book. 
     */ 
    public int getCurrentIndex() {
        return mCurrentIndex; 
    } 

    /** 
     * Initialize method. 
     */ 
    private void init(Context ctx) {
        mRenderer = new CurlRenderer(this);
        setRenderer(mRenderer); 
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 
        setOnTouchListener(this); 

        // Even though left and right pages are static we have to allocate room
        // for curl on them too as we are switching meshes. Another way would be
        // to swap texture ids only. 
        mPageLeft = new CurlMesh(10);
        mPageRight = new CurlMesh(10);
        mPageCurl = new CurlMesh(10);
        mPageLeft.setFlipTexture(true); 
        mPageRight.setFlipTexture(false); 
    } 

    @Override 
    public void onDrawFrame() {
        //TODO:on draw frame 
        // We are not animating. 
        if (mAnimate == false) {
            return; 
        } 
        long currentTime = System.currentTimeMillis(); 
        // If animation is done. 
        if (currentTime >= mAnimationStartTime + mAnimationDurationTime) {
            if (mAnimationTargetEvent == SET_CURL_TO_RIGHT) { 
                // Switch curled page to right. 
                CurlMesh right = mPageCurl; 
                CurlMesh curl = mPageRight; 
                right.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)); 
                right.setFlipTexture(false); 
                right.reset(); 
                mRenderer.removeCurlMesh(curl); 
                mPageCurl = curl; 
                mPageRight = right; 
                // If we were curling left page update current index. 
                if (mCurlState == CURL_LEFT) { 
                    --mCurrentIndex; 
                } 
            } else if (mAnimationTargetEvent == SET_CURL_TO_LEFT) {
                // Switch curled page to left. 
                CurlMesh left = mPageCurl; 
                CurlMesh curl = mPageLeft; 
                left.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)); 
                left.setFlipTexture(true); 
                left.reset(); 
                mRenderer.removeCurlMesh(curl); 
                if (!mRenderLeftPage) { 
                    mRenderer.removeCurlMesh(left); 
                } 
                mPageCurl = curl; 
                mPageLeft = left; 
                // If we were curling right page update current index. 
                if (mCurlState == CURL_RIGHT) { 
                    ++mCurrentIndex; 
                } 
            } 
            mCurlState = CURL_NONE; 
            mAnimate = false; 
            requestRender(); 
        } else { 
            mPointerPos.mPos.set(mAnimationSource); 
            float t = 1f - ((float) (currentTime - mAnimationStartTime) / mAnimationDurationTime);
            t = 1f - (t * t * t * (3 - 2 * t));
            mPointerPos.mPos.x += (mAnimationTarget.x - mAnimationSource.x) * t; 
            mPointerPos.mPos.y += (mAnimationTarget.y - mAnimationSource.y) * t; 
            updateCurlPos(mPointerPos); 
        } 
    } 

    @Override 
    public void onPageSizeChanged(int width, int height) {
        mPageBitmapWidth = width; 
        mPageBitmapHeight = height; 
        updatePages(); 
        requestRender(); 
    } 

    @Override 
    public void onSizeChanged(int w, int h, int ow, int oh) {
        super.onSizeChanged(w, h, ow, oh); 
        requestRender(); 
        if (mSizeChangedObserver != null) {
            mSizeChangedObserver.onSizeChanged(w, h); 
        } 
    } 

    @Override 
    public void onSurfaceCreated() {
        // In case surface is recreated, let page meshes drop allocated texture
        // ids and ask for new ones. There's no need to set textures here as
        // onPageSizeChanged should be called later on. 
        mPageLeft.resetTexture(); 
        mPageRight.resetTexture(); 
        mPageCurl.resetTexture(); 
    } 

    @Override 
    public boolean onTouch(View view, MotionEvent me) {
        // No dragging during animation at the moment. 
        // TODO: Stop animation on touch event and return to drag mode. 
        if (mAnimate || mPageProvider == null) {
            return false;
        } 

        // We need page rects quite extensively so get them for later use. 
        RectF rightRect = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT); 
        RectF leftRect = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT); 

        // Store pointer position. 
        mPointerPos.mPos.set(me.getX(), me.getY()); 
        mRenderer.translate(mPointerPos.mPos); 
         
        if (mEnableTouchPressure) { 
            mPointerPos.mPressure = me.getPressure(); 
        } else { 
            mPointerPos.mPressure = 0.8f; 
        } 

        switch (me.getAction()) { 
        case MotionEvent.ACTION_DOWN: { 

            // Once we receive pointer down event its position is mapped to
            // right or left edge of page and that'll be the position from where
            // user is holding the paper to make curl happen.
            mDragStartPos.set(mPointerPos.mPos); 
            //mDragStartPos.y = 0.0f; 
            // First we make sure it's not over or below page. Pages are
            // supposed to be same height so it really doesn't matter do we use
            // left or right one. 
            if (mDragStartPos.y > rightRect.top) { 
                mDragStartPos.y = rightRect.top; 
            } else if (mDragStartPos.y < rightRect.bottom) {
                mDragStartPos.y = rightRect.bottom; 
            } 

            // Then we have to make decisions for the user whether curl is going
            // to happen from left or right, and on which page. 
            if (mViewMode == SHOW_TWO_PAGES) { 
                // If we have an open book and pointer is on the left from right
                // page we'll mark drag position to left edge of left page. 
                // Additionally checking mCurrentIndex is higher than zero tells
                // us there is a visible page at all. 
                if (mDragStartPos.x < rightRect.left && mCurrentIndex > 0) {
                    mDragStartPos.x = leftRect.left; 
                    startCurl(CURL_LEFT); 
                } 
                // Otherwise check pointer is on right page's side. 
                else if (mDragStartPos.x >= rightRect.left
                        && mCurrentIndex < mPageProvider.getPageCount()) { 
                    mDragStartPos.x = rightRect.right; 
                    if (!mAllowLastPageCurl 
                            && mCurrentIndex >= mPageProvider.getPageCount() - 1) {
                        return false;
                    } 
                    startCurl(CURL_RIGHT); 
                } 
            } else if (mViewMode == SHOW_ONE_PAGE) {
                float halfX = (leftRect.right + leftRect.left) / 2;
                if (mDragStartPos.x < halfX && mCurrentIndex > 0) {
                    mDragStartPos.x = leftRect.left; 
                    startCurl(CURL_LEFT); 
                } else if (mDragStartPos.x >= halfX
                        && mCurrentIndex < mPageProvider.getPageCount()) { 
                    mDragStartPos.x = rightRect.left; 
                    if (!mAllowLastPageCurl 
                            && mCurrentIndex >= mPageProvider.getPageCount() - 1) {
                        return false;
                    } 
                    startCurl(CURL_RIGHT); 
                } 
            } 
            // If we have are in curl state, let this case clause flow through
            // to next one. We have pointer position and drag position defined
            // and this will create first render request given these points. 
            if (mCurlState == CURL_NONE) { 
                return false;
            } 
        } 
        case MotionEvent.ACTION_MOVE: { 
            updateCurlPos(mPointerPos); 
            break; 
        } 
        case MotionEvent.ACTION_CANCEL: 
        case MotionEvent.ACTION_UP: { 
            if (mCurlState == CURL_LEFT || mCurlState == CURL_RIGHT) {
                // Animation source is the point from where animation starts. 
                // Also it's handled in a way we actually simulate touch events
                // meaning the output is exactly the same as if user drags the
                // page to other side. While not producing the best looking
                // result (which is easier done by altering curl position and/or
                // direction directly), this is done in a hope it made code a
                // bit more readable and easier to maintain. 
                mAnimationSource.set(mPointerPos.mPos); 
                mAnimationStartTime = System.currentTimeMillis(); 

                // Given the explanation, here we decide whether to simulate
                // drag to left or right end. 
                if ((mViewMode == SHOW_ONE_PAGE && mPointerPos.mPos.x < (leftRect.left + leftRect.right) / 2)
                        || mViewMode == SHOW_TWO_PAGES && mPointerPos.mPos.x < rightRect.left) {
                    // On right side target is always right page's right border. 
                    mAnimationTarget.set(mDragStartPos); 
                    mAnimationTarget.x = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT).left; 
                    mAnimationTargetEvent = SET_CURL_TO_LEFT; 
                } else { 
                    // On left side target depends on visible pages. 
                    mAnimationTarget.set(mDragStartPos); 
                    if (mCurlState == CURL_RIGHT && mViewMode == SHOW_TWO_PAGES || mCurlState == CURL_LEFT && mPointerPos.mPos.x > rightRect.left) {
                        mAnimationTarget.x = rightRect.right; 
                    } else { 
                        mAnimationTarget.x = leftRect.right; 
                    } 
                    mAnimationTargetEvent = SET_CURL_TO_RIGHT; 
                } 
                mAnimate = true; 
                requestRender(); 
            } 
            break; 
        } 
        } 

        return true; 
    } 

    /** 
     * Allow the last page to curl. 
     */ 
    public void setAllowLastPageCurl(boolean allowLastPageCurl) {
        mAllowLastPageCurl = allowLastPageCurl; 
    } 

    /** 
     * Sets background color - or OpenGL clear color to be more precise. Color 
     * is a 32bit value consisting of 0xAARRGGBB and is extracted using 
     * android.graphics.Color eventually. 
     */ 
    @Override 
    public void setBackgroundColor(int color) {
        mRenderer.setBackgroundColor(color); 
        requestRender(); 
    } 

    /** 
     * Sets mPageCurl curl position. 
     */ 
    //TODO:startCurlPost 
    private void setCurlPos(PointF curlPos, PointF curlDir, double radius) {
        if (mCurlState == CURL_LEFT || (mCurlState == CURL_RIGHT && mViewMode == SHOW_ONE_PAGE)) {
            RectF pageRect = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT); 
            if (curlPos.x <= pageRect.left) { 
                mPageCurl.reset(); 
                requestRender(); 
                return; 
            } 
            if (curlPos.x > pageRect.right) { 
                curlPos.x = pageRect.right; 
            } 
            if (curlDir.y != 0) {
                float diffX = curlPos.x - pageRect.right; 
                float rightY = curlPos.y + (diffX * curlDir.x / curlDir.y);
                if (curlDir.y < 0 && rightY < pageRect.top) {
                    curlDir.x = pageRect.top - curlPos.y; 
                    curlDir.y = curlPos.x - pageRect.right; 
                } else if (curlDir.y > 0 && rightY > pageRect.bottom) {
                    curlDir.x = curlPos.y - pageRect.bottom; 
                    curlDir.y = pageRect.right - curlPos.x; 
                } 
            } 
        }else if(mCurlState == CURL_RIGHT){ 
            RectF pageRect = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT); 
            if (curlPos.x >= pageRect.right) { 
                mPageCurl.reset(); 
                requestRender(); 
                return; 
            } 
            if (curlPos.x < pageRect.left) { 
                curlPos.x = pageRect.left; 
            } 
            if (curlDir.y != 0) {
                float diffX = curlPos.x - pageRect.left; 
                float leftY = curlPos.y + (diffX * curlDir.x / curlDir.y);
                if (curlDir.y < 0 && leftY < pageRect.top) {
                    curlDir.x = curlPos.y - pageRect.top; 
                    curlDir.y = pageRect.left - curlPos.x; 
                } else if (curlDir.y > 0 && leftY > pageRect.bottom) {
                    curlDir.x = pageRect.bottom - curlPos.y; 
                    curlDir.y = curlPos.x - pageRect.left; 
                } 
            } 
        } 

        // Finally normalize direction vector and do rendering. 
        double dist = Math.sqrt(curlDir.x * curlDir.x + curlDir.y * curlDir.y);
        if (dist != 0) { 
            curlDir.x /= dist; 
            curlDir.y /= dist; 
            mPageCurl.curl(curlPos, curlDir, radius); 
        } else { 
            mPageCurl.reset(); 
        } 

        requestRender(); 
    } 

    /** 
     * Set current page index. Page indices are zero based values presenting 
     * page being shown on right side of the book. E.g if you set value to 4; 
     * right side front facing bitmap will be with index 4, back facing 5 and 
     * for left side page index 3 is front facing, and index 2 back facing (once 
     * page is on left side it's flipped over). 
     *  
     * Current index is rounded to closest value divisible with 2. 
     */ 
    public void setCurrentIndex(int index) {
        if (mPageProvider == null || index < 0) {
            mCurrentIndex = 0; 
        } else { 
            if (mAllowLastPageCurl) { 
                mCurrentIndex = Math.min(index, mPageProvider.getPageCount()); 
            } else { 
                mCurrentIndex = Math.min(index, 
                        mPageProvider.getPageCount() - 1); 
            } 
        } 
        updatePages(); 
        requestRender(); 
    } 

    /** 
     * If set to true, touch event pressure information is used to adjust curl 
     * radius. The more you press, the flatter the curl becomes. This is 
     * somewhat experimental and results may vary significantly between devices. 
     * On emulator pressure information seems to be flat 1.0f which is maximum 
     * value and therefore not very much of use. 
     */ 
    public void setEnableTouchPressure(boolean enableTouchPressure) {
        mEnableTouchPressure = enableTouchPressure; 
    } 

    /** 
     * Set margins (or padding). Note: margins are proportional. Meaning a value 
     * of .1f will produce a 10% margin. 
     */ 
    public void setMargins(float left, float top, float right, float bottom) {
        mRenderer.setMargins(left, top, right, bottom); 
    } 

    /** 
     * Update/set page provider. 
     */ 
    public void setPageProvider(PageProvider pageProvider) {
        mPageProvider = pageProvider; 
        mCurrentIndex = 0; 
        updatePages(); 
        requestRender(); 
    } 

    /** 
     * Setter for whether left side page is rendered. This is useful mostly for 
     * situations where right (main) page is aligned to left side of screen and 
     * left page is not visible anyway. 
     */ 
    public void setRenderLeftPage(boolean renderLeftPage) {
        mRenderLeftPage = renderLeftPage; 
    } 

    /** 
     * Sets SizeChangedObserver for this View. Call back method is called from 
     * this View's onSizeChanged method. 
     */ 
    public void setSizeChangedObserver(SizeChangedObserver observer) {
        mSizeChangedObserver = observer; 
    } 

    /** 
     * Sets view mode. Value can be either SHOW_ONE_PAGE or SHOW_TWO_PAGES. In 
     * former case right page is made size of display, and in latter case two 
     * pages are laid on visible area. 
     */ 
    public void setViewMode(int viewMode) {
        switch (viewMode) { 
        case SHOW_ONE_PAGE: 
            mViewMode = viewMode; 
            mPageLeft.setFlipTexture(false); 
            mRenderer.setViewMode(CurlRenderer.SHOW_ONE_PAGE); 
            mRenderer.setRightToLeft(RIGHT_TO_LEFT); 
            break; 
        case SHOW_TWO_PAGES: 
            mViewMode = viewMode; 
            mPageLeft.setFlipTexture(false); 
            mRenderer.setViewMode(CurlRenderer.SHOW_TWO_PAGES); 
            break; 
        } 
    } 

    /** 
     * Switches meshes and loads new bitmaps if available. Updated to support 2 
     * pages in landscape 
     */ 
    private void startCurl(int page) {
        switch (page) { 
        //TODO:starcurl 
        // Once right side page is curled, first right page is assigned into
        // curled page. And if there are more bitmaps available new bitmap is
        // loaded into right side mesh. 
        case CURL_RIGHT: { 
            // Remove meshes from renderer. 
            mRenderer.removeCurlMesh(mPageLeft); 
            mRenderer.removeCurlMesh(mPageRight); 
            mRenderer.removeCurlMesh(mPageCurl); 

            // We are curling right page. 
            CurlMesh curl = mPageRight; 
            mPageRight = mPageCurl; 
            mPageCurl = curl; 

            if (mCurrentIndex > 0) {
                mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)); 
                mPageLeft.setFlipTexture(true); 
                mPageLeft.reset(); 
                if (mRenderLeftPage) { 
                    mRenderer.addCurlMesh(mPageLeft); 
                } 
            } 
            if (mCurrentIndex < mPageProvider.getPageCount() - 1) {
                updatePage(mPageRight.getTexturePage(), mCurrentIndex + 1);
                mPageRight.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)); 
                mPageRight.setFlipTexture(false); 
                mPageRight.reset(); 
                mRenderer.addCurlMesh(mPageRight); 
            } 
             
            // How dragging previous page happens depends on view mode. 
            if (mViewMode == SHOW_ONE_PAGE || (mCurlState == CURL_LEFT && mViewMode == SHOW_TWO_PAGES)) {
                mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)); 
                mPageCurl.setFlipTexture(true); 
            } else { 
                mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)); 
                mPageCurl.setFlipTexture(false); 
            } 
             
            mPageCurl.reset(); 
            mRenderer.addCurlMesh(mPageCurl); 

            mCurlState = CURL_RIGHT; 
            break; 
        } 

        // On left side curl, left page is assigned to curled page. And if
        // there are more bitmaps available before currentIndex, new bitmap
        // is loaded into left page. 
        case CURL_LEFT: { 
            // Remove meshes from renderer. 
            mRenderer.removeCurlMesh(mPageLeft); 
            mRenderer.removeCurlMesh(mPageRight); 
            mRenderer.removeCurlMesh(mPageCurl); 

            // We are curling left page. 
            CurlMesh curl = mPageLeft; 
            mPageLeft = mPageCurl; 
            mPageCurl = curl; 

            if (mCurrentIndex > 1) {
                updatePage(mPageLeft.getTexturePage(), mCurrentIndex - 2);
                mPageLeft.setFlipTexture(true); 
                mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)); 
                mPageLeft.reset(); 
                if (mRenderLeftPage) { 
                    mRenderer.addCurlMesh(mPageLeft); 
                } 
            } 

            // If there is something to show on right page add it to renderer. 
            if (mCurrentIndex < mPageProvider.getPageCount()) {
                mPageRight.setFlipTexture(false); 
                mPageRight.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)); 
                mPageRight.reset(); 
                mRenderer.addCurlMesh(mPageRight); 
            } 

            mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)); 
            mPageCurl.setFlipTexture(true); 
            mPageCurl.reset(); 
            mRenderer.addCurlMesh(mPageCurl); 

            mCurlState = CURL_LEFT; 
            break; 
        } 

        } 
    } 

    /** 
     * Updates curl position. 
     */ 
    @SuppressLint("FloatMath") 
    private void updateCurlPos(PointerPosition pointerPos) {

        // Default curl radius. 
        double radius = mRenderer.getPageRect(CURL_RIGHT).width() / 3;
        // TODO: This is not an optimal solution. Based on feedback received so
        // far; pressure is not very accurate, it may be better not to map
        // coefficient to range [0f, 1f] but something like [.2f, 1f] instead. 
        // Leaving it as is until get my hands on a real device. On emulator
        // this doesn't work anyway. 
        radius *= Math.max(1f - pointerPos.mPressure, 0f);
        // NOTE: Here we set pointerPos to mCurlPos. It might be a bit confusing
        // later to see e.g "mCurlPos.x - mDragStartPos.x" used. But it's
        // actually pointerPos we are doing calculations against. Why? Simply to
        // optimize code a bit with the cost of making it unreadable. Otherwise
        // we had to this in both of the next if-else branches. 
        mCurlPos.set(pointerPos.mPos); 
        //mCurlPos.y = 0.0f; 
        // If curl happens on right page, or on left page on two page mode, 
        // we'll calculate curl position from pointerPos. 
        if (mCurlState == CURL_LEFT || (mCurlState == CURL_RIGHT && mViewMode == SHOW_TWO_PAGES)) {

            mCurlDir.x = mCurlPos.x - mDragStartPos.x; 
            mCurlDir.y = mCurlPos.y - mDragStartPos.y; 
            float dist = (float) Math.sqrt(mCurlDir.x * mCurlDir.x + mCurlDir.y * mCurlDir.y);

            // Adjust curl radius so that if page is dragged far enough on
            // opposite side, radius gets closer to zero. 
            float pageWidth = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)
                    .width(); 
            double curlLen = radius * Math.PI; 
            if (dist > (pageWidth * 2) - curlLen) {
                curlLen = Math.max((pageWidth * 2) - dist, 0f);
                radius = curlLen / Math.PI; 
            } 

            // Actual curl position calculation. 
            if (dist >= curlLen) { 
                double translate = (dist - curlLen) / 2;
                if (mViewMode == SHOW_TWO_PAGES) { 
                    mCurlPos.x -= mCurlDir.x * translate / dist; 
                } else { 
                    float pageLeftX = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT).left;
                    radius = Math.max(Math.min(mCurlPos.x - pageLeftX, radius), 0f);
                } 
                mCurlPos.y -= mCurlDir.y * translate / dist; 
            } else { 
                double angle = Math.PI * Math.sqrt(dist / curlLen);
                double translate = radius * Math.sin(angle); 
                mCurlPos.x += mCurlDir.x * translate / dist; 
                mCurlPos.y += mCurlDir.y * translate / dist; 
            } 
        } 
        // Otherwise we'll let curl follow pointer position. 
        else if (mCurlState == CURL_RIGHT) {

            // Adjust radius regarding how close to page edge we are. 
            float pageLeftX = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT).left;
            radius = Math.max(Math.min(mCurlPos.x - pageLeftX, radius), 0f);

            float pageRightX = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT).right;
            mCurlPos.x -= Math.min(pageRightX - mCurlPos.x, radius); 
            mCurlDir.x -= mCurlPos.x - mDragStartPos.x; 
            mCurlDir.y = mCurlPos.y - mDragStartPos.y; 
        } 

        setCurlPos(mCurlPos, mCurlDir, radius); 
    } 

    /** 
     * Updates given CurlPage via PageProvider for page located at index. 
     */ 
    private void updatePage(CurlPage page, int index) {
        // First reset page to initial state. 
        page.reset(); 
        // Ask page provider to fill it up with bitmaps and colors. 
        mPageProvider.updatePage(page, mPageBitmapWidth, mPageBitmapHeight, 
                index); 
    } 

    /** 
     * Updates bitmaps for page meshes. 
     */ 
    private void updatePages() {
        if (mPageProvider == null || mPageBitmapWidth <= 0
                || mPageBitmapHeight <= 0) { 
            return; 
        } 

        // Remove meshes from renderer. 
        mRenderer.removeCurlMesh(mPageLeft); 
        mRenderer.removeCurlMesh(mPageRight); 
        mRenderer.removeCurlMesh(mPageCurl); 

        int leftIdx = mCurrentIndex - 1;
        int rightIdx = mCurrentIndex; 
        int curlIdx = -1;
        if (mCurlState == CURL_LEFT) { 
            curlIdx = leftIdx; 
            --leftIdx; 
        } else if (mCurlState == CURL_RIGHT) {
            curlIdx = rightIdx; 
            ++rightIdx; 
        } 

        if (rightIdx >= 0 && rightIdx < mPageProvider.getPageCount()) {
            updatePage(mPageRight.getTexturePage(), rightIdx); 
            mPageRight.setFlipTexture(false); 
            mPageRight.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)); 
            mPageRight.reset(); 
            mRenderer.addCurlMesh(mPageRight); 
        } 
        if (leftIdx >= 0 && leftIdx < mPageProvider.getPageCount()) {
            updatePage(mPageLeft.getTexturePage(), leftIdx); 
            mPageLeft.setFlipTexture(true); 
            mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)); 
            mPageLeft.reset(); 
            if (mRenderLeftPage) { 
                mRenderer.addCurlMesh(mPageLeft); 
            } 
        } 
        if (curlIdx >= 0 && curlIdx < mPageProvider.getPageCount()) {
            updatePage(mPageCurl.getTexturePage(), curlIdx); 

            if (mCurlState == CURL_RIGHT) { 
                mPageCurl.setFlipTexture(true); 
                mPageCurl.setRect(mRenderer 
                        .getPageRect(CurlRenderer.PAGE_RIGHT)); 
            } else { 
                mPageCurl.setFlipTexture(false); 
                mPageCurl 
                        .setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)); 
            } 

            mPageCurl.reset(); 
            mRenderer.addCurlMesh(mPageCurl); 
        } 
    } 

    /** 
     * Provider for feeding 'book' with bitmaps which are used for rendering 
     * pages. 
     */ 
    public interface PageProvider {

        /** 
         * Return number of pages available. 
         */ 
        public int getPageCount();

        /** 
         * Called once new bitmaps/textures are needed. Width and height are in 
         * pixels telling the size it will be drawn on screen and following them 
         * ensures that aspect ratio remains. But it's possible to return bitmap 
         * of any size though. You should use provided CurlPage for storing page 
         * information for requested page number.<br/> 
         * <br/> 
         * Index is a number between 0 and getBitmapCount() - 1. 
         */ 
        public void updatePage(CurlPage page, int width, int height, int index);
    } 

    /** 
     * Simple holder for pointer position. 
     */ 
    private class PointerPosition {
        PointF mPos = new PointF(); 
        float mPressure; 
    } 

    /** 
     * Observer interface for handling CurlView size changes. 
     */ 
    public interface SizeChangedObserver {

        /** 
         * Called once CurlView size changes. 
         */ 
        public void onSizeChanged(int width, int height);
    } 

}

Transjakarta Android Application Part1

hm...setelah punya samsung galaxy dengan spek yang lumayan...saatnya dipake' buat dioprek-oprek...heuheu...

oke pengoprekan pertama adalah bagaimana sih cara membuat aplikasi android. sebenernya sudah banyak artikel yang dipublish bahkan temen-temen bisa liat di situs developer androidnya langsung..silahkan dicekidot..!!

kalo disimpulkan sih untuk membuat aplikasi android, yang dibutuhkan cukup simple...
kita hanya perlu :
1.SDK android ini untuk merunning virtual android
2.eclipse sebagai tools programingnya
3.ADT plugins eclipse untuk android

semuanya sudah tersedia di situs developer android.

setelah menginstall SDK kita harus terlebih dahulu mendownload versi androidnya yang.
Transjakarta - Download Android Version

untuk menginstall ADT kedalam eclipse pilih help -> install new software kemudian click "button add" kemudian click "archive" semudian cari file ADT yang sudah kita download sebelumnya.

From Transjakarta - Install New Software


jika kita sudah menginstall tiga kebutuhan diatas berarti kita sudah siap untuk mendevelop aplikasi android pertama kita..

untuk membuat aplikasi android kita dapat membuatnya dengan membuat project baru pada eclipse click new -> others pilih folder android kemudian pilih "android project" setelah itu silahkan beri nama project, package dan pilih android versi brapa yang akan kita develop kemudian click finish.

dalam membuat aplikasi android ada foder hal dasar yang perlu diketahui adalah :
1.scr -> tempat source code java
2.res/layout xml -> design tampilan
3.res -> resource yang dipakai didalam aplikasi kita

From Transjakarta - Folder Tree


untuk menjalankan atau merunning nya kita tinggal mengclick run kemudian pilih nama aplikasi kita, eclipse akan otomatis merunning virtual android dan menjalankan aplikasi yang telah kita buat. untuk membuat aplikasinya silahkan kunjungi halaman berikutnya salam dreamfighter:

Transjakarta Android Application Part2

Programming Contest

Soal 1 [A + B]

diberikan 2 buah integer A dan B yang belum pasti merupakan bilangan basis-10, temukannilai terkecul yang mungkin dari A+B dalam basis-10,

sebagai contoh,
A=213 kemungkinannya basis-4 (39 dalam basis-10)
A=4721 kemungkinannya basis-8 (2513 dalam basis-10)
A+B=39+2513=2552

Format Input :
baris pertama dari input terduru daru sebuah bilangan bulat positif T (1<=T<=100), banyaknya test case, masing-masing test case mempunyia dua bilangan bulat positif A dan B, A dan B akan terfiri paling banyak 5 digit, masibg-masing digit di antara 0 dan 9 (termauk 0 dan 9), dan tidak di awali dengan nol.

Format Output :
untuk masinbg-masing test case, outputkan bilangan bulat dalam basis-10 yang menyatakan nilai terkecil yang mungkin dari A+B

Contoh Input
2
213 4721
1001 90
Output untuk contoh input :
2552
99


Dibawah ini adalah salah satu dari solusi problem diatas...



#include "stdio.h"

int main()
{
int a[10],b[10];
int i,n,j,k;
int x[5],y[5];
int max=0,temp;
int divs,pow,pangkat;

scanf("%d",&n);
for (i=0;i<n;i++){
scanf("%d %d",&a[i],&b[i]);
divs=10000;
temp=a[i];
max=0;
for(j=0;j<5;j++){
x[j]=temp/divs;
temp=temp%divs;
divs=divs/10;
if(x[j]>max)
max=x[j];
}

a[i]=0;
for(j=4;j>=0;j--){
if(max<2){
pangkat=2;
}else if(max<4){
pangkat=4;
}else if(max<8){
pangkat=8;
}else if(max<10){
pangkat=10;
}
pow=1;

for(k=0;k<4-j;k++){
pow=pow*pangkat;
}

a[i]=a[i]+(x[j]*pow);
}

max=0;
divs=10000;
temp=b[i];
max=0;
for(j=0;j<5;j++){
x[j]=temp/divs;
temp=temp%divs;
divs=divs/10;
if(x[j]>max)
max=x[j];
}

b[i]=0;
for(j=4;j>=0;j--){
if(max<2){
pangkat=2;
}else if(max<4){
pangkat=4;
}else if(max<8){
pangkat=8;
}else if(max<10){
pangkat=10;
}
pow=1;

for(k=0;k<4-j;k++){
pow=pow*pangkat;
}

b[i]=b[i]+(x[j]*pow);
}
}

for(i=0;i<n;i++){
printf("%d\n",a[i]+b[i]);
}
return 0;
}

Menampilkan Video Binary Color dari Webcam dengan C# Emgu Library

Biasanya ketika kita akan membangun sebuah aplikasi pencitraan antau pengenalan pattenr terlebih dahulu kita harus meng extract ciri yang ada dalam sebuah citra. caranya adalah dengan membuat citra kita menjadi citra binary atau threshold yaitu citra yang hanya terdiri dari warna hitam dan putih saja. seperti contoh dibawah ini.







using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.UI;
using Emgu.CV.Structure;


namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Capture cap;

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
webCamCapture.TimeToCapture_milliseconds = 20;
webCamCapture.Start(0);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{

}
private Bitmap flipHorizontal(Image bmp){
Bitmap b = new Bitmap(bmp);
b.RotateFlip(RotateFlipType.RotateNoneFlipX);
return b;
}
private void webCamCapture_ImageCaptured(object source, WebCam_Capture.WebcamEventArgs e)
{
this.pictureBox1.Image = flipHorizontal(e.WebCamImage);
}

private void button2_Click(object sender, EventArgs e)
{
cap = new Capture(); //create a camera captue
cap.FlipHorizontal = true; //flipHorizontal camera
cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 240); //set height of camera
cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 320); //set width of camera
timer1.Enabled = true;
}

private void timer1_Tick(object sender, EventArgs e)
{
Image img;
Emgu.CV.Structure.Gray g = new Gray(100);
Emgu.CV.Structure.Gray g2 = new Gray(125);

pictureBox1.Image = cap.QueryGrayFrame().ThresholdBinaryInv(g,g2).ToBitmap();
}
}
}

Error Compile Visual C++ 2008 (EMM intrinsics not supported in the pure mode!)

hm.....

Jika temen-temen mendapatkan kesalahan "EMM intrinsics not supported in the pure mode!" ketika mengcompile project yang sedang temen-temen buat maka solusinya adalah dengan mengganti option Common Language Runtime Support yaitu dengan cara menuju ke menu

Project -> nama_project properties -> Configuration Properties -> General

kemudian ganti option Common Language Runtime Support dari "Pure MSIL Common Language Runtime Support (/clr:pure)" menjadi "Common Language Runtime Support (/clr)"

Download Video Youtube Without Video Downloader (Download Video Streaming Tanpa Video Downloader)

Bagaimana cara mendownload video youtube, streaming, dan yang lainya tanpa menggunakan video downloader?? bisakah?? mendowload video hanya menggunakan opera ataupun Mozilla Firefox??

saya punya sedikit trik nih caranya gampang banget.....[Khusus Menggunakan Windows]

1.buka film yang mau di download di situs yang sering anda kunjungi misalkan http://www.youtube.com/watch?v=E4Fbk52Mk1w


2.Kemudian biarkan video berjalan hingga selesai

3.Jika sudah selesai buka windows explorer


4.Kemudian buka folder C:\Documents and Settings\[User Yang Sedang Aktif]*\Local Settings\Application Data\Mozilla\Firefox\Profiles\0o1tvjdg.default\Cache [kalo yang anda pakai untuk membuka situs diatas adalah firefox]

C:\Documents and Settings\[User Yang Sedang Aktif]*\Local Settings\Application Data\Opera\Opera\profile\cache4 [kalo yang anda pakai untuk membuka situs diatas adalah opera]

*misalkan kita login dengan user zeger berarti folder yang harus di buka adalah C:\Documents and Settings\zeger\Local Settings\Application Data\Mozilla\Firefox\Profiles\0o1tvjdg.default\Cache

5.Setelah itu urutkan berdasarkan size atau berdasarkan tanggal, cari file yang ukurannya lebih besar dari yang kebanyakan file yang ada, jika di urutkan berdasarkan tanggal cari di bagian bawah folder, copy ke folder lain misalnya "My Documents" kemudian ganti atau tambah extensinya menjadi *.flv misalkan dari nama file "opr004B7" menjadi "opr004B7.flv"

6.Buka Menggunakan Media Player Clasic

7.Dan Tara....

Create Bounce Ball With Flash

1.Seperti biasa buat file baru dengan cara file->new

2.Buat sebuah object atau gambar bola

3.seleksi object yang baru kita buat menjadi sebuah movieclip dengan
cara click kanan->convert to symbol

4.click kiri object yang sudah diconvert menjadi movieclip kemudian buka action script
panel dengan menekan f9

5.masukkan script dibawah ini kedalam panel action script



onClipEvent (load) {
_xspeed = random(10)-random(9);
_yspeed = random(10)-random(9);
_x = random(200)+20;
_y = random(200)+20;
persentase=5
}
onClipEvent (enterFrame) {
_x = _x+_xspeed;
_y = _y+_yspeed;
if (_x<0) {
_xspeed = -_xspeed;
} else if (_x>530) {
_xspeed = -_xspeed;
}
if (_y<0) {
_yspeed = -_yspeed;
} else if (_y>389) {
_yspeed = -_yspeed;
}
for (i=0; i<_root.jum; i++) {
jarakx = _x-_root["bola"+i]._x;
jaraky = _y-_root["bola"+i]._y;
jarak = Math.sqrt(jarakx*jarakx+jaraky*jaraky);
if (jarak<18) {
if (Math.abs(_xspeed)>Math.abs(_root["bola"+i]._xspeed)) {
if (_root["bola"+i]._xspeed>0) {
_root["bola"+i]._xspeed = _root["bola"+i]._xspeed+(Math.abs(_xspeed)/persentase);
} else {
_root["bola"+i]._xspeed = _root["bola"+i]._xspeed-(Math.abs(_xspeed)/persentase);
}
if (_xspeed>0) {
_xspeed = _xspeed-(Math.abs(_xspeed)/persentase);
} else {
_xspeed = _xspeed+(Math.abs(_xspeed)/persentase);
}
_root["bola"+i]._xspeed = -_root["bola"+i]._xspeed;
_xspeed = -_xspeed;
} else if (Math.abs(_yspeed)>Math.abs(_root["bola"+i]._yspeed)) {
if (_root["bola"+i]._yspeed>0) {
_root["bola"+i]._yspeed = _root["bola"+i]._yspeed+(Math.abs(_yspeed)/persentase);
} else {
_root["bola"+i]._yspeed = _root["bola"+i]._yspeed-(Math.abs(_yspeed)/persentase);
}
if (_yspeed>0) {
_yspeed = _yspeed-(Math.abs(_yspeed)/persentase);
} else {
_yspeed = _yspeed+(Math.abs(_yspeed)/persentase);
}
_yspeed = -_yspeed;
_root["bola"+i]._yspeed = -_root["bola"+i]._yspeed;
}
}
}
}



6.click kiri object kemudian beri nama instance "bola" pada panel properties

7.buka panel action

8.masukkan script dibawah ini kedalam panel action script


bola._visible = false;
jum = 15;
for(i=0;i< jum;i++) {
duplicateMovieClip(bola, "bola"+i, i++);
}


source bounce_ball.zip