
正文
抛物线java代码 抛物线快捷公式
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
android想要画一个抛物线,怎么实现
效果图中,抛物线的动画即是由SurfaceView实现的。底部栏中的文字翻转详情相关帖子:
[Android] 文字翻转动画的实现
需求:
1.实现抛物线动画
1.1 设计物理模型,能够根据时间变量计算出某个时刻图片的X/Y坐标。
1.2 将图片高频率(相比于UI线程的缓慢而言)刷新到界面中。这儿需要实现将脏界面清屏及刷新操作。
2.文字翻转动画(已解决,见上面的帖子链接)
下面来逐一解决所提出的问题。
-----------------------------------------------------------------------------
分隔线内容与Android无关,请慎读,勿拍砖。谢啦
1.1 设计物理模型,如果大家还记得初中物理时,这并不难。自己写的草稿图见下:
可以有:图片要从高度为H的位置下落,并且第一次与X轴碰撞时会出现能量损失,至原来的N%。并且我们需要图片的最终落点离起始位置在X轴上的位移为L,默认存在重力加速度g。
详细的物理分析见上图啦,下面只说代码中如何实现,相关代码在PhysicalTool.java。
第一次下落过程所耗时t1与高度height会有如下关系:
[java] view plaincopy
t1 = Math.sqrt(2 * height * 1.0d / GRAVITY);
[java] view plain copy
t1 = Math.sqrt(2 * height * 1.0d / GRAVITY);
第一次与X轴碰撞后上升至最高点的耗时t2与高度 N%*height会有:
[java] view plaincopy
t2 = Math.sqrt((1 - WASTAGE) * 2 * height * 1.0d / GRAVITY);
[java] view plain copy
t2 = Math.sqrt((1 - WASTAGE) * 2 * height * 1.0d / GRAVITY);
那么总的动画时间为(t1 + t2 + t2),则水平位移速度有(width为X轴总位移):
[java] view plaincopy
velocity = width * 1.0d / (t1 + 2 * t2);
[java] view plain copy
velocity = width * 1.0d / (t1 + 2 * t2);
则根据时间计算图片的实时坐标有:
PhysicalTool.comput()
[java] view plaincopy
double used = (System.currentTimeMillis() - startTime) * 1.0d / 1000;
x = velocity * used;
if (0 = used used t1) {
y = height - 0.5d * GRAVITY * used * used;
} else if (t1 = used used (t1 + t2)) {
double tmp = t1 + t2 - used;
y = (1 - WASTAGE) * height - 0.5d * GRAVITY * tmp * tmp;
} else if ((t1 + t2) = used used (t1 + 2 * t2)) {
double tmp = used - t1 - t2;
y = (1 - WASTAGE) * height - 0.5d * GRAVITY * tmp * tmp;
}
[java] view plain copy
double used = (System.currentTimeMillis() - startTime) * 1.0d / 1000;
x = velocity * used;
if (0 = used used t1) {
y = height - 0.5d * GRAVITY * used * used;
} else if (t1 = used used (t1 + t2)) {
double tmp = t1 + t2 - used;
y = (1 - WASTAGE) * height - 0.5d * GRAVITY * tmp * tmp;
} else if ((t1 + t2) = used used (t1 + 2 * t2)) {
double tmp = used - t1 - t2;
y = (1 - WASTAGE) * height - 0.5d * GRAVITY * tmp * tmp;
}
Android无关内容结束了。
----------------------------------------------------------------------------------------
1.2 SurfaceView刷新界面
SurfaceView是一个特殊的UI组件,特殊在于它能够使用非UI线程刷新界面。至于为何具有此特殊性,将在另一个帖子"SurfaceView 相关知识笔记"中讨论,该帖子将讲述SurfaceView、Surface、ViewRoot、Window Manager/Window、Canvas等之间的关系。
使用SurfaceView需要自定义组件继承该类,并实现SurfaceHolder.Callback,该回调提供了三个方法:
[java] view plaincopy
surfaceCreated()//通知Surface已被创建,可以在此处启动动画线程
surfaceChanged()//通知Surface已改变
surfaceDestroyed()//通知Surface已被销毁,可以在此处终止动画线程
[java] view plain copy
surfaceCreated()//通知Surface已被创建,可以在此处启动动画线程
surfaceChanged()//通知Surface已改变
surfaceDestroyed()//通知Surface已被销毁,可以在此处终止动画线程
SurfaceView使用有一个原则,即该界面操作必须在surfaceCreated之后及surfaceDestroyed之前。该回调的监听通过SurfaceHolder设置。代码如下:
[java] view plaincopy
//于SurfaceView类中,该类实现SurfaceHolder.Callback接口,如本例中的ParabolaView
SurfaceHolder holder = getHolder();
holder.addCallback(this);
[java] view plain copy
//于SurfaceView类中,该类实现SurfaceHolder.Callback接口,如本例中的ParabolaView
SurfaceHolder holder = getHolder();
holder.addCallback(this);
示例代码中,通过启动DrawThread调用handleThread()实现对SurfaceView的刷新。
刷新界面首先需要执行holder.lockCanvas()锁定Canvas并获得Canvas实例,然后进行界面更新操作,最后结束锁定Canvas,提交界面更改,至Surface最终显示在屏幕上。
代码如下:
[java] view plaincopy
canvas = holder.lockCanvas();
… … … …
… … … …
canvas.drawBitmap(bitmap, x, y, paint);
holder.unlockCanvasAndPost(canvas);
[java] view plain copy
canvas = holder.lockCanvas();
… … … …
… … … …
canvas.drawBitmap(bitmap, x, y, paint);
holder.unlockCanvasAndPost(canvas);
本例中,需要清除屏幕脏区域,出于简便的做法,是将整个SurfaceView背景重复地设置为透明,代码为:
[java] view plaincopy
canvas.drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);
[java] view plain copy
canvas.drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);
对于SurfaceView的操作,下面这个链接讲述得更详细,更易理解,推荐去看下:
Android开发之SurfaceView
惯例,Java代码如下,XML请自行实现
本文由Sodino所有,转载请注明出处:
[java] view plaincopy
ActSurfaceView.java
package lab.sodino.surfaceview;
import lab.sodino.surfaceview.RotateAnimation.InterpolatedTimeListener;
import android.app.Activity;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
public class ActSurfaceView extends Activity implements OnClickListener, ParabolaView.ParabolaListener, Callback,
InterpolatedTimeListener {
public static final int REFRESH_TEXTVIEW = 1;
private Button btnStartAnimation;
/** 动画界面。 */
private ParabolaView parabolaView;
/** 购物车处显示购物数量的TextView。 */
private TextView txtNumber;
/** 购物车中的数量。 */
private int number;
private Handler handler;
/** TextNumber是否允许显示最新的数字。 */
private boolean enableRefresh;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
handler = new Handler(this);
number = 0;
btnStartAnimation = (Button) findViewById(R.id.btnStartAnim);
btnStartAnimation.setOnClickListener(this);
parabolaView = (ParabolaView) findViewById(R.id.surfaceView);
parabolaView.setParabolaListener(this);
txtNumber = (TextView) findViewById(R.id.txtNumber);
}
public void onClick(View v) {
if (v == btnStartAnimation) {
LogOut.out(this, "isShowMovie:" + parabolaView.isShowMovie());
if (parabolaView.isShowMovie() == false) {
number++;
enableRefresh = true;
parabolaView.setIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
// 设置起始Y轴高度和终止X轴位移
parabolaView.setParams(200, ((ViewGroup) txtNumber.getParent()).getLeft());
parabolaView.showMovie();
}
}
}
public void onParabolaStart(ParabolaView view) {
}
public void onParabolaEnd(ParabolaView view) {
handler.sendEmptyMessage(REFRESH_TEXTVIEW);
}
public boolean handleMessage(Message msg) {
switch (msg.what) {
case REFRESH_TEXTVIEW:
if (txtNumber.getVisibility() != View.VISIBLE) {
txtNumber.setVisibility(View.VISIBLE);
}
RotateAnimation anim = new RotateAnimation(txtNumber.getWidth() 1, txtNumber.getHeight() 1,
RotateAnimation.ROTATE_INCREASE);
anim.setInterpolatedTimeListener(this);
txtNumber.startAnimation(anim);
break;
}
return false;
}
@Override
public void interpolatedTime(float interpolatedTime) {
// 监听到翻转进度过半时,更新txtNumber显示内容。
if (enableRefresh interpolatedTime 0.5f) {
txtNumber.setText(Integer.toString(number));
// Log.d("ANDROID_LAB", "setNumber:" + number);
enableRefresh = false;
}
}
}
相关问答
Q1: java一个小圆球抛物线运动,请问抛物线的运动怎么实现?
1、首先描一个坐标轴
2、确定方程式
3、打点
4、连线
5、取出打点的坐标,按照顺序依次变更颜色(做出运动效果)
6、简单的一元二次方程举例【步骤5留给题主思考】
public class View extends JFrame {
public View() {
JFrame frame = new JFrame("Equation");
frame.getContentPane().setLayout(new BorderLayout());
JPanel panel1 = new JPanel();
panel1.setPreferredSize(new Dimension(50, 50));
JLabel labelA = new JLabel();
labelA.setText("a");
JTextField textA = new JTextField("0",3);
JLabel labelB = new JLabel();
labelB.setText("b");
JTextField textB = new JTextField("0",3);
JLabel labelC = new JLabel();
labelC.setText("c");
JTextField textC = new JTextField("0",3);
JButton draw = new JButton();
draw.setText("Draw");
draw.addActionListener( new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
Controller.a = Double.parseDouble(textA.getText());
Controller.b = Double.parseDouble(textB.getText());
Controller.c = Double.parseDouble(textC.getText());
repaint();
frame.pack();
frame.setSize(420,490);
}
});
panel1.add(labelA);
panel1.add(textA);
panel1.add(labelB);
panel1.add(textB);
panel1.add(labelC);
panel1.add(textC);
panel1.add(draw);
JPanel panel2 = new JPanel(){
public void paint(Graphics g){
super.paint(g);
Controller.grid(g);
Controller.Graphic1(g);
}
};
panel2.setBackground(Color.WHITE);
frame.getContentPane().add(panel1, BorderLayout.PAGE_START);
frame.getContentPane().add(panel2, BorderLayout.CENTER);
frame.setVisible(true);
frame.setSize(420,490);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
View frame = new View();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public class Controller {
static double a=2, b=1, c=0;
public static void grid (Graphics g){
g.setColor(Color.blue);
g.drawLine(200,0,200,400);
g.drawLine(0,200,400,200);
for (int x=0; x=400; x= x +40){
g.drawLine(x,195,x,205);
}
for (int y=0; y=400; y=y+40){
g.drawLine(195,y,205,y);
}
}
public static void Graphic1(Graphics g) {
g.setColor(Color.red);
for (double x=-100;x=100;x = x+0.1){
double y = a * x * x + b * x + c;
int X = (int)Math.round(200 + x*20);
int Y = (int)Math.round(200 - y*20);
g.fillOval(X-2,Y-2,4,4);
}
}
}
Q2: 用java画抛物线怎么弄
抛物线是怎么样的? y= a * x *x +b? 这个你比我懂。。
知道方程了,画线就是若干点之间的连线,也就是画 poly
至于用java 画还是c来画 或者是 C#来画,完全就是各种API的调用问题。
我估计你之所以要问,主要是不知道java 图形界面(窗体)如何生成? 那需要用 swing
角度问题 可能是最麻烦的。。。如果我来想,我会: 找到抛物线中最顶的点 P1和两边的等高点 P2,P3 用 p2-p1 得到向量 V1 用p3-p1得到向量 V2 用向量的点积来计算出角度。 当然思考是这样,画的时候就得跟据这种考虑来定点的位置了。。。 仅供参考。
Q3: 关于java中模拟抛物线轨迹的问题
看了这套题目感觉很有兴趣,就花了一个中午亲手给你写了一个类似的例子,相信可以帮助你对这个游戏有很好的理解,从右向左那个是僵尸,点一下鼠标就出现植物,我只是起到一个抛砖引玉的作用。代码如下(绝对可以用的代码):
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.event.MouseInputAdapter;
public class PlantsAndZombies extends JFrame {
private static final long serialVersionUID = 1L;
public static final int screenWidth=800;
public static final int screenHeight=600;
Printer printer;
Zombies zombies=new Zombies();
Thread T_Zombies;
Bullet bullet=new Bullet();
Thread T_Bullet;
public PlantsAndZombies(){
this.setSize(new Dimension(screenWidth,screenHeight));
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.addMouseListener(new Shoot(this));
this.setVisible(true);
printer=new Printer( this.getGraphics());
printer.Add(zombies);
printer.Add(bullet);
T_Zombies=new Thread(zombies);
T_Zombies.start();
T_Bullet=new Thread(bullet);
T_Bullet.start();
}
public void Shoot(){
bullet.getTarget(zombies);
}
public static void main(String[] args){
PlantsAndZombies game=new PlantsAndZombies();
}
public void run() {
while(true){
}
}
}
interface Drawable{
void drawMe(Graphics g);
}
class Zombies implements Drawable,Runnable{
public boolean isLive=true;
public int x=PlantsAndZombies.screenWidth;
public int y=500;
public void run() {
while(true){
if(x10){
x-=20;
}else x=PlantsAndZombies.screenWidth;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void drawMe(Graphics g){
g.drawRect(x,y,20,50);
}
}
class Bullet implements Drawable,Runnable{
private int x=0;
private int y=500;
private Zombies _z;
private float a,b,c;
private float step;
public void getTarget(Zombies z){
_z=z;
// 用三点确定一个抛物线的方法,计算弹道
int x1=0;
int y1=500;
int x2=(z.x-6*20)/2;
int y2=300; // 抛物线高度200个像素
int x3=z.x-6*20; // 假设击中僵尸用3秒钟,在这3秒钟内僵尸向前移动了6*20个像素
int y3=500;
a=(float)((y2-y1)*(x3-x2)-(y3-y2)*(x2-x1))/(float)((x2*x2-x1*x1)*(x3-x2)-(x3*x3-x2*x2)*(x2-x1));
b=(float)((y2-y1)-a*(x2*x2-x1*x1))/(float)(x2-x1);
c=y1-a*x1*x1-b*x1;
step=(float)(x3-x1)/(float)(3*20);
}
public void run() {
while(true){
try {
x+=step;
y=(int)(a*x*x+b*x+c);
if(y500){
_z.isLive=false;
}
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void drawMe(Graphics g) {
g.drawRect(x,y,20,20);
}
}
class Printer extends Thread{
private VectorDrawable v=new VectorDrawable();
private Graphics _g;
public Printer(Graphics g){
_g=g;
this.start();
}
public void Add(Drawable o){
v.add(o);
}
public void run(){
while(true){
_g.clearRect(0,0,PlantsAndZombies.screenWidth,PlantsAndZombies.screenHeight);
for(Drawable o:v){
o.drawMe(_g);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Shoot extends MouseInputAdapter{
private PlantsAndZombies _adaptee;
public Shoot(PlantsAndZombies adaptee){
_adaptee=adaptee;
}
public void mouseClicked(MouseEvent e) {
_adaptee.Shoot();
}
}
Q4: eclipse中Java在控制台做像抛物线一样输出*
……首先,这个明显不是抛物线,而是sin/cos曲线
我习惯用轻量组件
取两个数,x1和y1,x从最左边到最右边循环赋值,y1=f(x1)
再取两个数,x2和y2,x2就是下一个x1的值,y2=f(x2)
其中f(x)是一个函数,可以是sin(x),也可以是x的平方。
创建一个JPanel,但是别直接定义JPanel类,你需要这样创建:
ClassName variable = new ClassName(parameters);
其中这个ClassName,需要你继承JPanel,并覆盖里边的paintComponent(Graphics g)方法,不这样创建是画不出来的。
接下来就开始画,g.drawLine(x1, y1, x2, y2),精度可能不高,但是效果是如图的。
哎呀我靠逗比了,答完了才看见是在控制台输出的
前面也不用删,但是把
g.drawLine(x1, y1, x2, y2)
换成
g.drawRect(x1, y1, 1, 1)
比较好,x2和y2就扔了吧。
要在控制台输出,先定义一下每行长度和宽度,也就是横坐标和纵坐标。
越多越精细,但是太多了也不行,一行打不出来,会很……
然后用下面的两个句子:
BufferedImage b=new BufferedImage(刚才那个面板的长度、宽度、1是三个需要传递的参数);
某个面板.paint(b.createGraphics());
这样把面板上显示的内容输入在一个名字叫b的图像里
这时候就可以用两个循环嵌套,来挨个检查b上的每一个点的颜色,用这个句子:
int color=b.getRGB(x, y);其中x和y分别是横纵坐标。color就是一个16进制的数字
转成红绿蓝三色,就用下面这个:
int r=(color0xff0000)16, g=(color0xff00)8, b=color0xff;
(重名什么的去死吧!)
然后我们一般都是用黑笔来画函数图像对吧,就用if语句判断红绿蓝是否都为0,如果是则系统打印一个*号,如果不是则系统打印一个空格。
最后再加一行,当横坐标超出时,系统打印一个转行符。
Q5: JAVA 抛物线和坐标轴
这个其实很简单 sine在java函数里面传的是幅度值,你用一for循环自增变量表示幅度的增加,用sine(x)值的函数值表示y值这样不断的画点 ,密集的点就可以形成sianwave,当然你还可以选择 画线段 相邻两个点之间的线段越密集就越容易形成sine线
关于抛物线java代码和抛物线快捷公式的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。






