360°平滑游戏摇杆 Rocker

public class Rocker extends Activity{
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(new RockerView(this));
	}
	
	private class RockerView extends SurfaceView implements SurfaceHolder.Callback,Runnable{
		private SurfaceHolder mSurfaceHolder;
		private Thread mThread;
		private Canvas mCanvas;
		private Paint mPaint;
		private boolean mIsFlag;
		
		private float mCircleX=100;
		private float mCircleY=100;
		private float mCircleR=50;
		private float mRockerCircleX=100;
		private float mRockerCircleY=100;
		private float mRockerCircleR=20;

		public RockerView(Context context) {
			super(context);
			
			mSurfaceHolder=this.getHolder();
			mSurfaceHolder.addCallback(this);
			mPaint=new Paint();
			mPaint.setAntiAlias(true);
			
			setFocusable(true);
			setFocusableInTouchMode(true);
			
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			mIsFlag=true;
			mThread=new Thread(this);
			mThread.start();
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			mIsFlag=false;
		}
		
		@Override
		public boolean onTouchEvent(MotionEvent event) {
			if (event.getAction()==MotionEvent.ACTION_DOWN||event.getAction()==MotionEvent.ACTION_MOVE) {
				if (Math.sqrt((Math.pow(mCircleX-event.getX(), 2)+Math.pow(mCircleY-event.getY(), 2)))>mCircleR) {
					double angle=getAngle(mCircleX,mCircleY,event.getX(),event.getY());
					setRockerXYInCircle(angle);
				}else {
					mRockerCircleX=event.getX();
					mRockerCircleY=event.getY();
				}
				return true;
			}else if (event.getAction()==MotionEvent.ACTION_UP) {
				mRockerCircleX=mCircleX;
				mRockerCircleY=mCircleY;
				return true;
			}
			
			return super.onTouchEvent(event);
		}

		private void setRockerXYInCircle(double angle) {
			mRockerCircleX=(float)(mCircleR*Math.cos(angle))+mCircleX;
			mRockerCircleY=(float)(mCircleR*Math.sin(angle))+mCircleY;
		}

		private double getAngle(float circleX, float circleY, float targetX, float targetY) {
			float disX=targetX-circleX;
			float disY=targetY-circleY;
			float hypotenuse=(float)Math.sqrt(Math.pow(disX, 2)+Math.pow(disY, 2));
			float cosAngle=disX/hypotenuse;
			float angle=(float)Math.acos(cosAngle);
			if (targetY<circleY) {
				angle=-angle;
			}
			return angle;
		}

		@Override
		public void run() {
			while (mIsFlag) {
				doDraw();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		private void doDraw() {
			try {
				mCanvas=mSurfaceHolder.lockCanvas();
				if (mCanvas!=null) {
					mCanvas.drawColor(Color.WHITE);
					mPaint.setColor(0x70000000);
					mCanvas.drawCircle(mCircleX, mCircleY, mCircleR, mPaint);
					mPaint.setColor(0x70ff0000);
					mCanvas.drawCircle(mRockerCircleX, mRockerCircleY, mRockerCircleR, mPaint);
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				if (mCanvas!=null) {
					mSurfaceHolder.unlockCanvasAndPost(mCanvas);
				}
			}
		}
		
	}

}

问题一:

@Override
		public boolean onTouchEvent(MotionEvent event) {
			if (event.getAction()==MotionEvent.ACTION_DOWN||event.getAction()==MotionEvent.ACTION_MOVE) {
				if (Math.sqrt((Math.pow(mCircleX-event.getX(), 2)+Math.pow(mCircleY-event.getY(), 2)))>mCircleR) {
					double angle=getAngle(mCircleX,mCircleY,event.getX(),event.getY());
					setRockerXYInCircle(angle);
				}else {
					mRockerCircleX=event.getX();
					mRockerCircleY=event.getY();
				}
				return true;
			}else if (event.getAction()==MotionEvent.ACTION_UP) {
				mRockerCircleX=mCircleX;
				mRockerCircleY=mCircleY;
				return true;
			}
			
			return super.onTouchEvent(event);
		}
这个是当if (event.getAction()==MotionEvent.ACTION_DOWN||event.getAction()==MotionEvent.ACTION_MOVE) 当手指按下和移动的时候,计算摇杆的x和y坐标,当手指抬起的时候恢复和大圆相同的x和y坐标,再进行绘制的时候就会画在中间

问题二:

private void setRockerXYInCircle(double angle) {
			mRockerCircleX=(float)(mCircleR*Math.cos(angle))+mCircleX;
			mRockerCircleY=(float)(mCircleR*Math.sin(angle))+mCircleY;
		}
当手指移动的距离大于大圆的半径的时候,要重新计算摇杆的x和y坐标,使其仍然在大圆的圆周上,也就是是大圆圆心和手指所在点的直线与圆周相交的点。
问题三:

private double getAngle(float circleX, float circleY, float targetX, float targetY) {
			float disX=targetX-circleX;
			float disY=targetY-circleY;
			float hypotenuse=(float)Math.sqrt(Math.pow(disX, 2)+Math.pow(disY, 2));
			float cosAngle=disX/hypotenuse;
			float angle=(float)Math.acos(cosAngle);
			if (targetY<circleY) {
				angle=-angle;
			}
			return angle;
		}
这个还不是太理解,看来数学退化了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
曲柄摇杆机构是一种常见的机械结构,其位移分析可以使用C语言进行模拟计算。具体步骤如下: 1. 定义曲柄摇杆机构的参数,包括曲柄半径、连杆长度、摇杆长度等。 2. 定义曲柄、连杆、摇杆的运动方程,在C语言中可以使用数学函数库(如math.h)来实现三角函数的计算。 3. 设定时间步长和模拟时间,通过循环计算每个时间点各个零件的位移和角度变化。 4. 输出结果,可以将每个时间点的各个零件位移和角度变化保存在数组中,也可以将结果输出到文件中。 以下是一个简单的曲柄摇杆机构位移分析的C语言代码示例: ``` #include <stdio.h> #include <math.h> #define PI 3.1415926 int main() { double crank_r = 10; // 曲柄半径 double rod_l = 30; // 连杆长度 double rocker_l = 40; // 摇杆长度 double theta1 = 0; // 曲柄角度 double theta2 = 0; // 连杆角度 double theta3 = 0; // 摇杆角度 double delta_t = 0.01; // 时间步长 double t = 0; // 模拟时间 while (t < 10) // 模拟10秒钟 { // 计算各个零件的位移和角度变化 double x1 = crank_r * cos(theta1); double y1 = crank_r * sin(theta1); double x2 = x1 + rod_l * cos(theta2); double y2 = y1 + rod_l * sin(theta2); double x3 = x2 + rocker_l * cos(theta3 + PI); double y3 = y2 + rocker_l * sin(theta3 + PI); // 输出结果 printf("t=%.2f, x1=%.2f, y1=%.2f, x2=%.2f, y2=%.2f, x3=%.2f, y3=%.2f\n", t, x1, y1, x2, y2, x3, y3); // 更新角度 theta1 += 0.1 * delta_t; theta2 = acos((pow(x2 - x1, 2) + pow(y2 - y1, 2) - pow(rod_l, 2) - pow(crank_r, 2)) / (2 * rod_l * crank_r)); theta3 = acos((pow(x3 - x2, 2) + pow(y3 - y2, 2) - pow(rocker_l, 2) - pow(rod_l, 2)) / (2 * rocker_l * rod_l)) - PI; // 更新时间 t += delta_t; } return 0; } ``` 上述代码中,我们使用了cos和sin等数学函数计算各个零件的位移和角度变化,并通过while循环模拟了10秒钟的机构运动,并输出了各个零件的坐标。在实际应用中,可以根据需要修改参数和运动方程,以实现不同种类的机构分析。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值