台球是很常见的一种休闲方式。但是玩好它并不是那么容易的,于是,自己搞了个代码模拟了一下。简单研究其内在规律。
package basic.overrr;
public class TableBallCalculator {
/**
*
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
double a = 5.0;
double c = 10.0;
double b = Math.log10(c*c)/Math.log10(a*a);
b = Math.pow(100-25, 0.5);
b = b-1;
System.out.println("b= :"+b);
System.out.println("sin 1/2 :"+Math.sin(30 * Math.PI/180));
System.out.println("b= :"+Math.atan(b/5) *180.0 / Math.PI);
TableBallCalculator t = new TableBallCalculator();
System.out.println("mainas :"+t.getAngles(8, 10, 0, 0));
}
double a;// 假设已知
double b;// 假设已知
double c;// 假设未知
double d;// 假设未知
double _a;//角度alpha,以度记,非弧度。假设已知 以_开头表示角度
double _b;//角度beta 。假设已知
double _c;//角度西格玛------求出西格玛,然后返回90-西格玛 即为所求!
/**
*
* 思路,先求c、后d,最后 _c ,返回 _b - (90 - _c)
*
* b 应该永远大于等于1
*/
public double[] getAngles(double aa,double bb,double _aa,double _bb) {
a = aa;
b = bb;
_a = _aa;
_b = _bb;
c = b * Math.cos(_b*Math.PI/180);
_c = Math.atan(b * Math.sin(_b*Math.PI/180)/(c-1));
_c = _c * 180.0 / Math.PI;
// return 90-_c;
double _a$ = Math.atan(0.5/a) * 180.0 / Math.PI;
System.out.println("偏角 _a$ :"+_a$);
double best = Math.atan(b * Math.sin(_b*Math.PI/180)/((b * Math.cos(_b*Math.PI/180))-1)) * 180.0 / Math.PI-_b;
_b = _b -_a$;
double min = Math.atan(b * Math.sin(_b*Math.PI/180)/((b * Math.cos(_b*Math.PI/180))-1)) * 180.0 / Math.PI-_b;
_b = _b + 2*_a$;
double max = Math.atan(b * Math.sin(_b*Math.PI/180)/((b * Math.cos(_b*Math.PI/180))-1)) * 180.0 / Math.PI-_b;
// System.out.println("最小角 _a$ :"+min);
System.out.println("最佳角 _a$ :"+best);
// System.out.println("最大角 _a$ :"+max);
return new double[]{min,best,max};
}
}
实得分
package basic.overrr;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TableBallCanvas {
public void init() {
// TODO Auto-generated method stub
}
public static void main(String arg[]) {
JFrame f = new JFrame("Paint");
f.setSize(1500, 1500);
f.setVisible(true);
MyPanel1 mp = new MyPanel1();
f.add(mp);
f.setSize(1000,700);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
class MyPanel1 extends JPanel
{
// 覆盖JPanel的paint方法
public void paint(Graphics g) // Graphics是绘图的重要类,画笔类
{// paint(Graphic g)绘制组件的外观,repaint()刷新组件的外观
// 1.调用父类函数完成初始化
// 这句话,不能少
super.paint(g);
g.drawLine(30, this.getHeight()-30, this.getWidth(), this.getHeight()-30);
g.drawLine(30, 0, 30, this.getHeight()-30);
g.drawString("O", 15,this.getHeight()-15);
aa(g);
for (int i = 0; i < this.getHeight()-30 ; i=i+50) {
g.drawString(""+i/20, 8,this.getHeight()-30-i);
}
g.drawString("Y the distance B",this.getWidth(),this.getHeight()-15);
goWithAngleB(g);
}
//angleB fixed to 45
private void goWithDistinceB(Graphics g) {
double step = 0.1;
TableBallCalculator tcc = new TableBallCalculator();
double aa = 5;
double bb = 1;
double _aa = 0;
double _bb = 45;
double[] angles = null;
double oldX = 0;
double oldY = 0;
int multiply = 10;
System.out.println("this.getHeight() : "+this.getHeight());
// 以横坐标为角度, 纵坐标为 最佳偏角
while (bb <= 20) {
angles = tcc.getAngles(aa, bb, _aa, _bb);
double best = angles[1];
Point point = new Point((int)(_bb*multiply),(int)(best*multiply));
// g.drawOval(point.x, point.y, 2, 2);
g.drawLine((int)(oldX*multiply)+30,this.getHeight()-30-(int)(oldY*multiply),
(int)(bb*multiply) +30,this.getHeight()-30-(int)(best*multiply));
if((int)bb%5==0) {
}
g.drawLine((int)(oldX*multiply)+30,this.getHeight()-300-(int)(bb/best),
(int)(bb*multiply) +30,this.getHeight()-300-(int)(bb/best));
oldX = bb;
oldY = best;
bb = bb +0.1;
// System.out.println("(_bb/best):==" + (_bb/best));
}
for (int i = 1; i <= 20 ; i=i+2) {
g.drawString(""+i,(int)(i*multiply)+30,this.getHeight()-15);
}
g.drawString("X the distance B",this.getWidth(),this.getHeight()-15);
}
private void goWithAngleB(Graphics g) {
double step = 0.1;
TableBallCalculator tcc = new TableBallCalculator();
double aa = 5;
double bb = 5;
double _aa = 0;
double _bb = 0;
double[] angles = null;
double oldX = 0;
double oldY = 0;
int multiply = 20;
System.out.println("this.getHeight() : "+this.getHeight());
// 以横坐标为角度, 纵坐标为 最佳偏角
while (_bb <= 80) {
angles = tcc.getAngles(aa, bb, _aa, _bb);
double best = angles[1];
Point point = new Point((int)(_bb*multiply),(int)(best*multiply));
// g.drawOval(point.x, point.y, 2, 2);
g.drawLine((int)(oldX*multiply)+30,this.getHeight()-30-(int)(oldY*multiply),
(int)(_bb*multiply) +30,this.getHeight()-30-(int)(best*multiply));
g.drawLine((int)(oldX*multiply)+30,this.getHeight()-30-(int)(_bb*180/best/Math.PI),
(int)(_bb*multiply) +30,this.getHeight()-30-(int)((_bb*180/best/Math.PI)));
oldX = _bb;
oldY = best;
_bb = _bb +0.1;
//System.out.println("(_bb/best):==" + (_bb/best));
}
for (int i = 1; i <= 80 ; i=i+2) {
g.drawString(""+i,(int)(i*multiply)+30,this.getHeight()-15);
}
g.drawString("X the distance B",this.getWidth(),this.getHeight()-15);
}
}
个人认为,台球是很有技术含量的一种活动,对体力的要求不大。 远不像足球篮球。当然,这样比较没意思。乒乓球也是很有技术含量的。各有千秋。
后面看了相关视频,觉得受益匪浅。
参考:http://www.wasu.cn/Play/show/id/535488
http://www.wasu.cn/Play/show/id/495596
未完待续。。