java - 如何从斜坡获得角度?
问题描述
所以我目前正在制作一个游戏,我需要从斜坡上获取我在游戏中工作的 AI 的角度。但是,它并没有按我的预期工作,并且只有在我使用这个功能时才会发生,我在做了几个小时的研究后制作了这个功能。
请记住,我在学校只学了代数和几何 1,我一直在尝试在空闲时间自学代数和几何 2 以及微积分。
public static double angleFromSlope(double rise, double run)
{
double r;
if (run == 0.0)
{
r = (Math.atan(0) * 180 / Math.PI);
} else if (rise == 0.0)
{
r = (Math.atan(0) * 180 / Math.PI);
} else
{
r = (Math.atan(rise / run) * 180 / Math.PI);
}
if (rise >= 0 && run >= 0)
{
return r;
}
else if (rise >= 0 && run <= 0)
{
return Math.abs(r + 90) + 90;
}
else if (rise < 0 && run < 0)
{
return Math.abs(Math.abs(r) + 180);
}
else
{
return Math.abs(r + 90) + 270;
}
}
编辑:
public static void main(String[] args)
{
double angle = 90;
double[] dir = DirFromAngle(angle);
System.out.println(dir[0] + " " + dir[1]);
double[] line = new double[]
{ 10, 10, 10 + (dir[0] * 10), 10 + (dir[1] * 10) };
double[] rn = riseOverRun(line);
double a = angleFromSlope(rn[0], rn[1]);
System.out.println(a);
}
public static double[] DirFromAngle(double angle)
{
double b = Math.toRadians(angle);
double[] output = new double[]
{ Math.sin(b), Math.cos(b) };
return output;
}
public static double[] riseOverRun(double[] line)
{
// 0 - X1, 1 - Y1, 2 - X2, 3 - Y2
double[] output = new double[]
{ (line[3] - line[1]), (line[2] - line[0]) };
return output;
}
public static double angleFromSlope(double rise, double run)
{
double r;
if (run == 0.0)
{
r = (Math.atan(0) * 180 / Math.PI);
} else if (rise == 0.0)
{
r = (Math.atan(0) * 180 / Math.PI);
} else
{
r = (Math.atan(rise / run) * 180 / Math.PI);
}
if (rise >= 0 && run >= 0)
{
return r;
}
else if (rise >= 0 && run <= 0)
{
return Math.abs(r + 90) + 90;
}
else if (rise < 0 && run < 0)
{
return Math.abs(Math.abs(r) + 180);
}
else
{
return Math.abs(r + 90) + 270;
}
}
解决方案
您最好使用点和线来解释您要计算的内容。一个点包含 x、y,一条线有 2 个点。画出形状也可以更好地理解。
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.List;
public class AngleFromSlope extends Canvas {
protected static class Point {
private final double x, y;
protected Point(double x, double y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("(");
builder.append(x);
builder.append(", ");
builder.append(y);
builder.append(")");
return builder.toString();
}
}
protected static class Line {
private final Point p1, p2;
protected Line(Point p1, Point p2) {
this.p1 = p1;
this.p2 = p2;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("[");
builder.append(p1);
builder.append(", ");
builder.append(p2);
builder.append("]");
return builder.toString();
}
}
protected List<Line> lines = new ArrayList<>();
public void paint(Graphics graphics) {
Graphics2D g2d = (Graphics2D) graphics.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
int m = getHeight()/2;
g2d.translate(0, m);
// flip about y-axis
g2d.scale(1,-1);
// first shift "up" (negative) m pixels
g2d.translate(0,-m);
for(Line line : lines) {
g2d.drawLine((int) line.p1.x, (int) line.p1.y, (int) line.p2.x, (int) line.p2.y);
System.out.println(line);
}
g2d.dispose();
}
public static void main(String [] args) throws java.io.IOException {
AngleFromSlope canvas = new AngleFromSlope();
java.awt.Frame frame = new java.awt.Frame("AngleFromSlope");
frame.setSize(500, 500);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
final int SCALE = 50;
final int BASE = 4, HEIGHT = 4;
Point a = new Point(SCALE, SCALE);
Point b = new Point(SCALE + BASE * SCALE, SCALE);
Point c = new Point(SCALE + BASE * SCALE, SCALE + HEIGHT * SCALE);
Line line1 = new Line(a, b);
canvas.lines.add(line1);
Line line2 = new Line(a, c);
canvas.lines.add(line2);
Line line3 = new Line(b, c);
canvas.lines.add(line3);
double slope = (c.y - a.y) / (c.x - a.x);
System.out.println("Slope: " + slope);
double theta = Math.atan(slope);
System.out.println("θ: " + Math.toDegrees(theta));
frame.add(canvas);
frame.setVisible(true);
frame.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
System.out.println("Closing program");
System.exit(0); }
} );
}
}
推荐阅读
- spring - 部署在 PCF 上的应用程序试图在 localhost:8888 处查找配置,即使云代工厂提供的配置服务器已与应用程序绑定
- python - 有选择地使用生成器项目
- java - 如何解决 java.sql.SQLSyntaxErrorException: ORA-00913: too many values
- spring-boot - Spring security:AuthenticationManager.authenticate() 执行什么功能
- c# - 通过 Python 从接口库中提取数字万用表数据读数的问题
- javascript - 是否可以在网页本身显示的网站内打开 .exe 文件,而不仅仅是在计算机上打开它
- swift - 为什么 IndexSet 可以用负数初始化?
- javascript - 如何将 AjaxData 与 Bjornblog Store Locator 一起使用
- scala - 将编译器生成的所有文件保存在 SBT 中
- javascript - 限制每个输入的 ajax 调用