JavaFX 函数图与 Wolfram Alpha 中的不同
JavaFX function plots are different than in Wolfram Alpha
我创建了一个计算器应用程序,它应该绘制 graphs.User 得到一个文本框,他可以在其中输入函数公式,然后对其进行验证并解析为 ChartXY 等等以绘制 it.Basicaly 我我正在使用 javafx.I 中的所有函数库,发现我的结果与函数 运行 相当 different.Most 非常好,但有些函数不同,就像我有实部 + 虚部但是wolfram 还有它的镜面反射 added.Plese 看看我的截图。
这个例子是关于 log(x) 域 (-6,6) codomain (-2,2)
Wolfram Alpha 复杂图形:
http://oi61.tinypic.com/2uij7l2.jpg
我的计算器应用截图:
http://oi62.tinypic.com/2m7xoi9.jpg
另一个例子是 log(sin(x)) domain(-6.3,6.3) codomain (-7,2)
Wolfram 真实版:http://oi57.tinypic.com/2a5hoif.jpg
Wolfram 复合体:http://oi59.tinypic.com/kesq49.jpg
我的计算器截图:
http://oi58.tinypic.com/2v13qpu.jpg
arctan(tan(x)) 域(-6.3,6.3) codomain(-2,2)
Wolfram 图:http://oi58.tinypic.com/hupze0.jpg
我的申请剧情:http://oi62.tinypic.com/8wktmr.jpg
我的问题是:是否应该是这样的,如果不是那么为什么会这样,是否可以修复?
这是我的 class 的一部分,其中包含所有解析
public class Controller {
@FXML
private TextField domainTextField;
@FXML
private TextField codomainTextField;
@FXML
private LineChart coordinateLineChart;
@FXML
private TextField functionTextField;
@FXML
private NumberAxis xNumberAxis;
@FXML
private NumberAxis yNumberAxis;
@FXML
private ComboBox lineStyleComboBox;
@FXML
private ComboBox lineThiknessComboBox;
@FXML
private ColorPicker colorPicker;
@FXML
private Pane numericPane;
@FXML
private TextField descriptionTextField;
@FXML
private Label descriptionLabel;
@FXML
private VBox legendVBox;
@FXML
private CheckBox modificationModeCheckBox;
@FXML
private AnchorPane toSnapshot;
Stage stage;
MessageBox msgBox;
Intervals intervals = new Intervals();
LinkedList<FunctionViewHelper> functions = new LinkedList<FunctionViewHelper>();
boolean axisXdescriptionFlag = true;
boolean editingMode = false;
int editingFunctionId = 0;
int fontFactor = 0;
ObservableList<XYChart.Series> seriesListChart = FXCollections.observableArrayList();
ArrayList<XYChart.Series> lastSeries = new ArrayList<XYChart.Series>();
ArrayList<CustomFunction> exp4jCustomFunction = new ArrayList<CustomFunction>();
// Draws a graph
private void drawFormula(Calculable expression, ArrayList<String> conditions, String cssStyle) throws ScriptException {
ArrayList<XYChart.Series> seriesList = new ArrayList<XYChart.Series>();
seriesList.add(new XYChart.Series());
double lastY = 0;
for (double x = intervals.domainStart; x < intervals.domainEnd; x += 0.009) {
if (Validator.ifAllConditionsTrue(conditions, x)) {
if (x != intervals.domainStart) lastY = expression.calculate();
expression.setVariable("x", x);
if (Math.abs(lastY - expression.calculate()) > Const.brakeLineConst)
seriesList.add(new XYChart.Series());
seriesList.get(seriesList.size() - 1).getData().add(new XYChart.Data(x, expression.calculate()));
}
}
seriesListChart.addAll(seriesList);
lastSeries.addAll(seriesList);
setSeriesStyle(seriesList, cssStyle);
}
// Parsing string to Calculable which we can draw.
private Calculable buildExpression(String expression) throws UnparsableExpressionException, UnknownFunctionException {
return new ExpressionBuilder(expression)
.withVariableNames("x")
.withCustomFunctions(exp4jCustomFunction)
.build();
}
private void drawButtonHandler() {
//TODO remove
//domainTextFieldOnChange();
Function function = null;
if (!Validator.validateFofEmptyFields(domainTextField, functionTextField)) {
msgBox.show("You have to specify domain and formula.");
return;
}
if (!Validator.validateIntervals(intervals, codomainTextField)) {
msgBox.show("Specify proper domain and codomain.");
return;
}
try {
if (!editingMode) {
function = new Function(functionTextField.getText(), colorPicker.getValue(), (String) lineStyleComboBox.getValue(),
lineThiknessComboBox.getValue().toString());
colorPicker.setValue(Const.getNextColor());
} else {
function = getByFunctionId(editingFunctionId).function;
function.formula = functionTextField.getText();
seriesListChart.removeAll(getByFunctionId(editingFunctionId).series);
}
ArrayList<String> conditions = new ArrayList<String>();
drawFunctionReq(function.formula, conditions, function.getCss());
if (!editingMode)
functions.add(new FunctionViewHelper(function, addLegendFunctionView(function), new ArrayList<XYChart.Series>(lastSeries)));
else {
getByFunctionId(editingFunctionId).series = new ArrayList<XYChart.Series>(lastSeries);
((Label) getByFunctionId(editingFunctionId).view.getChildren().get(1)).setText(function.formula);
}
} catch (UnknownFunctionException ex) {
ex.printStackTrace();
msgBox.show("Unknown function.");
} catch (UnparsableExpressionException ex) {
ex.printStackTrace();
msgBox.show("Unparsable expression.");
} catch (Exception ex) {
ex.printStackTrace();
msgBox.show("Unknown error.");
} finally {
lastSeries.clear();
}
}
@FXML
private void domainTextFieldOnChange() {
domainTextField.setStyle("");
try {
intervals.setDomain(domainTextField.getText());
xNumberAxis.lowerBoundProperty().set(intervals.domainStart);
xNumberAxis.upperBoundProperty().set(intervals.domainEnd);
} catch (Exception e) {
domainTextField.setStyle("-fx-focus-color: red;");
e.printStackTrace();
}
}
@FXML
private void codomainTextFieldOnChange() {
codomainTextField.setStyle("");
if (!codomainTextField.getText().isEmpty()) {
try {
intervals.setCodomain(codomainTextField.getText());
yNumberAxis.setAutoRanging(false);
yNumberAxis.setUpperBound(intervals.codomainEnd);
yNumberAxis.setLowerBound(intervals.codomainStart);
} catch (Exception e) {
codomainTextField.setStyle("-fx-focus-color: red;");
e.printStackTrace();
}
} else yNumberAxis.setAutoRanging(true);
}
WA是正确的。在虚部 arg(z) 中,在 z=0 处应该有一个从 pi 到 0 的跳跃。真正的分量是 log(|z|).
猜对了:计算角度一定要用arctan2。
我创建了一个计算器应用程序,它应该绘制 graphs.User 得到一个文本框,他可以在其中输入函数公式,然后对其进行验证并解析为 ChartXY 等等以绘制 it.Basicaly 我我正在使用 javafx.I 中的所有函数库,发现我的结果与函数 运行 相当 different.Most 非常好,但有些函数不同,就像我有实部 + 虚部但是wolfram 还有它的镜面反射 added.Plese 看看我的截图。
这个例子是关于 log(x) 域 (-6,6) codomain (-2,2)
Wolfram Alpha 复杂图形: http://oi61.tinypic.com/2uij7l2.jpg
我的计算器应用截图: http://oi62.tinypic.com/2m7xoi9.jpg
另一个例子是 log(sin(x)) domain(-6.3,6.3) codomain (-7,2)
Wolfram 真实版:http://oi57.tinypic.com/2a5hoif.jpg
Wolfram 复合体:http://oi59.tinypic.com/kesq49.jpg
我的计算器截图: http://oi58.tinypic.com/2v13qpu.jpg
arctan(tan(x)) 域(-6.3,6.3) codomain(-2,2)
Wolfram 图:http://oi58.tinypic.com/hupze0.jpg
我的申请剧情:http://oi62.tinypic.com/8wktmr.jpg
我的问题是:是否应该是这样的,如果不是那么为什么会这样,是否可以修复?
这是我的 class 的一部分,其中包含所有解析
public class Controller {
@FXML
private TextField domainTextField;
@FXML
private TextField codomainTextField;
@FXML
private LineChart coordinateLineChart;
@FXML
private TextField functionTextField;
@FXML
private NumberAxis xNumberAxis;
@FXML
private NumberAxis yNumberAxis;
@FXML
private ComboBox lineStyleComboBox;
@FXML
private ComboBox lineThiknessComboBox;
@FXML
private ColorPicker colorPicker;
@FXML
private Pane numericPane;
@FXML
private TextField descriptionTextField;
@FXML
private Label descriptionLabel;
@FXML
private VBox legendVBox;
@FXML
private CheckBox modificationModeCheckBox;
@FXML
private AnchorPane toSnapshot;
Stage stage;
MessageBox msgBox;
Intervals intervals = new Intervals();
LinkedList<FunctionViewHelper> functions = new LinkedList<FunctionViewHelper>();
boolean axisXdescriptionFlag = true;
boolean editingMode = false;
int editingFunctionId = 0;
int fontFactor = 0;
ObservableList<XYChart.Series> seriesListChart = FXCollections.observableArrayList();
ArrayList<XYChart.Series> lastSeries = new ArrayList<XYChart.Series>();
ArrayList<CustomFunction> exp4jCustomFunction = new ArrayList<CustomFunction>();
// Draws a graph
private void drawFormula(Calculable expression, ArrayList<String> conditions, String cssStyle) throws ScriptException {
ArrayList<XYChart.Series> seriesList = new ArrayList<XYChart.Series>();
seriesList.add(new XYChart.Series());
double lastY = 0;
for (double x = intervals.domainStart; x < intervals.domainEnd; x += 0.009) {
if (Validator.ifAllConditionsTrue(conditions, x)) {
if (x != intervals.domainStart) lastY = expression.calculate();
expression.setVariable("x", x);
if (Math.abs(lastY - expression.calculate()) > Const.brakeLineConst)
seriesList.add(new XYChart.Series());
seriesList.get(seriesList.size() - 1).getData().add(new XYChart.Data(x, expression.calculate()));
}
}
seriesListChart.addAll(seriesList);
lastSeries.addAll(seriesList);
setSeriesStyle(seriesList, cssStyle);
}
// Parsing string to Calculable which we can draw.
private Calculable buildExpression(String expression) throws UnparsableExpressionException, UnknownFunctionException {
return new ExpressionBuilder(expression)
.withVariableNames("x")
.withCustomFunctions(exp4jCustomFunction)
.build();
}
private void drawButtonHandler() {
//TODO remove
//domainTextFieldOnChange();
Function function = null;
if (!Validator.validateFofEmptyFields(domainTextField, functionTextField)) {
msgBox.show("You have to specify domain and formula.");
return;
}
if (!Validator.validateIntervals(intervals, codomainTextField)) {
msgBox.show("Specify proper domain and codomain.");
return;
}
try {
if (!editingMode) {
function = new Function(functionTextField.getText(), colorPicker.getValue(), (String) lineStyleComboBox.getValue(),
lineThiknessComboBox.getValue().toString());
colorPicker.setValue(Const.getNextColor());
} else {
function = getByFunctionId(editingFunctionId).function;
function.formula = functionTextField.getText();
seriesListChart.removeAll(getByFunctionId(editingFunctionId).series);
}
ArrayList<String> conditions = new ArrayList<String>();
drawFunctionReq(function.formula, conditions, function.getCss());
if (!editingMode)
functions.add(new FunctionViewHelper(function, addLegendFunctionView(function), new ArrayList<XYChart.Series>(lastSeries)));
else {
getByFunctionId(editingFunctionId).series = new ArrayList<XYChart.Series>(lastSeries);
((Label) getByFunctionId(editingFunctionId).view.getChildren().get(1)).setText(function.formula);
}
} catch (UnknownFunctionException ex) {
ex.printStackTrace();
msgBox.show("Unknown function.");
} catch (UnparsableExpressionException ex) {
ex.printStackTrace();
msgBox.show("Unparsable expression.");
} catch (Exception ex) {
ex.printStackTrace();
msgBox.show("Unknown error.");
} finally {
lastSeries.clear();
}
}
@FXML
private void domainTextFieldOnChange() {
domainTextField.setStyle("");
try {
intervals.setDomain(domainTextField.getText());
xNumberAxis.lowerBoundProperty().set(intervals.domainStart);
xNumberAxis.upperBoundProperty().set(intervals.domainEnd);
} catch (Exception e) {
domainTextField.setStyle("-fx-focus-color: red;");
e.printStackTrace();
}
}
@FXML
private void codomainTextFieldOnChange() {
codomainTextField.setStyle("");
if (!codomainTextField.getText().isEmpty()) {
try {
intervals.setCodomain(codomainTextField.getText());
yNumberAxis.setAutoRanging(false);
yNumberAxis.setUpperBound(intervals.codomainEnd);
yNumberAxis.setLowerBound(intervals.codomainStart);
} catch (Exception e) {
codomainTextField.setStyle("-fx-focus-color: red;");
e.printStackTrace();
}
} else yNumberAxis.setAutoRanging(true);
}
WA是正确的。在虚部 arg(z) 中,在 z=0 处应该有一个从 pi 到 0 的跳跃。真正的分量是 log(|z|).
猜对了:计算角度一定要用arctan2。