java - 我是否正确地将这个伪代码翻译成 Java?
问题描述
前几天 我在 Math.se 上问了这个问题,得到了伪代码的如下回答:
Function RandomCircleInside(centerX, centerY, radius):
Let newRadius = radius * Random()
Let radians = 2.0 * 3.14159265358979323846 * Random()
Let deviation = (radius - newRadius) * Sqrt(Random())
Let newX = centerX + deviation * Cos(radians)
Let newY = centerY + deviation * Sin(radians)
Return (newX, newY, newRadius)
End Function
我将伪代码更改为 Java,并添加了我自己的更改以满足我的需要。新代码如下所示:
Circle createNewCircle(int centerX, int centerY, int radius, int newR, Color newColor) {
int newRadius = radius * Random();
double radians = 2.0 * 3.141592653589793 * Random();
double deviation = (radius - newRadius) * Math.sqrt(Random());
System.out.println(radius + " - " + newRadius + " * sqrt(0 or 1) = " + (radius-newRadius) + " * (0 or 1) = " + deviation);
double newX = centerX + deviation * Math.cos(radians);
System.out.println(centerX + " + " + deviation + " * cos(" + radians + ") = " + (centerX + deviation) + " * " + Math.cos(radians));
double newY = centerY + deviation * Math.sin(radians);
int newCirX = (int) newX;
int newCirY = (int) newY;
Circle newCir = new Circle(newCirX, newCirY, newR*2, newR*2, newR, newColor, true);
return newCir;
}
代码本身应该在现有的 Circle 中创建一个新的 Circle。我创建了一个如下所示的圆形类:
import java.awt.Color;
import java.awt.Graphics;
public class Circle {
public int X, Y, Width, Height, radius;
public Color color;
public boolean toFill;
public Circle(int x, int y, int width, int height, int radius, Color color, boolean fill) {
X = x;
Y = y;
Width = width;
Height = height;
this.radius = radius;
this.color = color;
toFill = fill;
}
public void render(Graphics g) {
g.setColor(color);
for(int i=-5; i<5; i++) {
if(toFill) {
g.fillOval(X+i, Y+i, Width-i, Height-i);
} else {
g.drawOval(X+i, Y+i, Width-i, Height-i);
}
}
}
public boolean contains(Circle pBound) {
int pBoundCenterX = pBound.X+pBound.radius;
int cirCenterX = X+radius;
int diffBetweenCentersX = Math.abs(pBoundCenterX-cirCenterX);
int pBoundCenterY = pBound.Y+pBound.radius;
int cirCenterY = Y+radius;
int diffBetweenCentersY = Math.abs(pBoundCenterY-cirCenterY);
if(diffBetweenCentersX<= (pBound.radius+radius) && diffBetweenCentersX>=Math.abs(pBound.radius-radius)) { // X
if(diffBetweenCentersY>=Math.abs(pBound.radius-radius)) { // Y
return true;
}
}
return false;
}
public int getX() {
return X;
}
public int getWidth() {
return Width;
}
public int getRadius() {
return radius;
}
public void setWidth(int width) {
Width = width;
}
public int getHeight() {
return Height;
}
public void setHeight(int height) {
Height = height;
}
public void setX(int x) {
X = x;
}
public int getY() {
return Y;
}
public void setY(int y) {
Y = y;
}
}
我创建新圈子的方式是这样的:
if(secInGame==timesForCircle[X] && !hasChanged) { // circle 2
Circle cir1 = cir;
cir = createNewCircle(cir1.X+(cir1.Width/2), cir1.Y+(cir1.Height/2), cir1.getRadius(), 135, Color.cyan);
hasChanged = true;
circleOn++;
circ++;
}
cir1
先前存在的圈子在哪里cir
,新圈子在哪里。
有什么我没有正确编码的吗?我尝试了一些不同的变体,但它们都给出了相同的结果。
在我实现伪代码之前,我的圈子看起来像这样:
但现在看起来像这样:
我所有的代码都可以在 github 上找到:link
解决方案
我认为您的代码中有几个问题。
1.首先不清楚为什么你Circle
有radius
,Width
和Height
. 对于一个圆圈,所有三件事都应该相同。此外,您render
的万一看起来很奇怪toFill
。true
这是一个简化版本(注意:我没有编译它,所以可能会有一些错误):
public class Circle {
public int X, Y, radius;
public Color color;
public boolean toFill;
public Circle(int x, int y, int radius, Color color, boolean fill) {
X = x;
Y = y;
this.radius = radius;
this.color = color;
toFill = fill;
}
public void render(Graphics g) {
g.setColor(color);
final int r2 = 2*radius;
if(toFill) {
g.fillOval(X, Y, r2, r2);
}
else {
for(int i=-5; i<5; i++) {
g.drawOval(X+i, Y+i, r2-i, r2-i);
}
}
}
public boolean contains(Circle pBound) {
int pBoundCenterX = pBound.X+pBound.radius;
int cirCenterX = X+radius;
int diffBetweenCentersX = Math.abs(pBoundCenterX-cirCenterX);
int pBoundCenterY = pBound.Y+pBound.radius;
int cirCenterY = Y+radius;
int diffBetweenCentersY = Math.abs(pBoundCenterY-cirCenterY);
if(diffBetweenCentersX<= (pBound.radius+radius) && diffBetweenCentersX>=Math.abs(pBound.radius-radius)) { // X
if(diffBetweenCentersY>=Math.abs(pBound.radius-radius)) { // Y
return true;
}
}
return false;
}
public int getX() {
return X;
}
public int getRadius() {
return radius;
}
public void setX(int x) {
X = x;
}
public int getY() {
return Y;
}
public void setY(int y) {
Y = y;
}
}
我没有检查您的代码,但我认为这是一个好习惯:
- 重命名
x
和y
进入leftX
并topY
避免与centerX
/centerY
含义混淆。或将含义更改为更典型的含义center
。 - 将所有字段声明为
private
(请参阅封装); - 将所有字段声明为
final
并删除所有setXyz
方法(请参阅immutability)
2.我不明白为什么你createNewCircle
有newR
参数,同时你newRadius
在第一行生成一个随机数。其中之一绝对应该被删除。鉴于该参数始终是一个常数135
,我认为应该将其删除。
3.现在我相信你的翻译中的主要错误在于
int newCirX = (int) newX;
int newCirY = (int) newY;
它可能应该是这样的
int newCirX = (int) newX - newRadius;
int newCirY = (int) newY - newRadius;
看起来你搞乱了中心与左上角。实际上,我认为您犯了这样的错误这一事实是支持重命名的论据,x
我y
在第 1 项中提出了建议。
推荐阅读
- nuget - 如何设置 NuGet nuspec 的版本
从命令行? - ios - 在我的项目中,我有一个阅读功能。这本书是pdf格式的。我必须集成一个功能,比如暗模式,意味着,
- php - 在 codeigniter 中自动填充编辑表单
- javascript - 使用 Angular6 在 3 个元素之间切换类
- javascript - 如何将箭头功能更改为常规功能?
- python - 将多个工作簿中的数据复制并自动化到现有的主工作簿中,而不会丢失使用 python 的格式
- sql - 拆分具有分隔值的列并比较每个值
- reactjs - 我对组件生命周期方法声明中的此错误 Typo 感到震惊 react/no-typos
- c# - 在构建期间找出 PlatformNotSupportedException
- scala - 在 akka http 客户端中禁用 SSL 安全性