- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用递归绘制一棵树。树需要看起来像这样:
关于我应该如何做的简短总结:
length
,宽度为width
这是我解决问题的方法。我只想画树干,左分支和右分支。我设法做到了这一点,具有以下功能:
public void drawTree(double length, double min_length, double width, double alpha) {
//Draws the trunk of the tree
StdDraw.setPenRadius(width);
StdDraw.line(250, 150, 250, 150+length);
//Left branch
double hypotenuse = (3.0/4.0)*length;
double opposite = Math.sin(alpha) * hypotenuse;
double adjacent = Math.sqrt(Math.pow(hypotenuse, 2)-Math.pow(opposite, 2));
StdDraw.setPenRadius(width*3.0/4.0);
StdDraw.line(250,150+length,250-adjacent,150+length+opposite);
//Right branch
double hypotenuse2 = (2.0/3.0)*length;
double opposite2 = Math.sin(alpha) * hypotenuse2;
double adjacent2 = Math.sqrt(Math.pow(hypotenuse2, 2)-Math.pow(opposite2, 2));
StdDraw.setPenRadius(width*1.0/2.0);
StdDraw.line(250,150+length,250+adjacent2,150+length+opposite2);
}
这是输出,正如我想要的那样:
我以为剩下的会很容易,但在过去的 3 小时里我没有取得任何进展:/。我包括了停止条件的 if 语句。但是我对递归部分一无所知。我试过这个:
if (length > min_length) {
//Left branch
double hypotenuse = (3.0/4.0)*length;
double opposite = Math.sin(alpha) * hypotenuse;
double adjacent = Math.sqrt(Math.pow(hypotenuse, 2)-Math.pow(opposite, 2));
StdDraw.setPenRadius(width*3.0/4.0);
StdDraw.line(250,150+length,250-adjacent,150+length+opposite);
//Right branch
double hypotenuse2 = (2.0/3.0)*length;
double opposite2 = Math.sin(alpha) * hypotenuse2;
double adjacent2 = Math.sqrt(Math.pow(hypotenuse2, 2)-Math.pow(opposite2, 2));
StdDraw.setPenRadius(width*1.0/2.0);
StdDraw.line(250,150+length,250+adjacent2,150+length+opposite2);
//My first attempt
drawTree(hypotenuse*hypotenuse, min_length, width, alpha);
drawTree(hypotenuse2*hypotenuse2, min_length, width, alpha);
//My second attempt
drawTree(hypotenuse, min_length, width, alpha);
drawTree(hypotenuse2, min_length, width, alpha);
}
我理解简单的递归,例如阶乘、回文等,但我仍然坚持这一点,非常感谢任何帮助。
最佳答案
正如评论和当前答案中已经指出的那样,让 drawTree
方法不知道当前绘制的是树的哪一部分是至关重要的。
您不能在此方法中使用绝对坐标。而且您必须跟踪您当前所在的位置。例如,这可以通过将 Point2D
传递给描述当前树部分起点的递归方法来完成。
您甚至不需要明确的代码来绘制 Twig :请注意,单行 已经是一棵树。 Twig 只是“小树”:同样,它们是单行,但具有不同的长度和宽度。
(并且与之前的树相比有一定的角度。你没有提到这个,但是根据屏幕截图,角度似乎是Math.PI/5
)
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.function.DoubleConsumer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class RecursiveTreeDrawing
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
RecursiveTreeDrawingPanel p = new RecursiveTreeDrawingPanel();
p.setPreferredSize(new Dimension(500,500));
f.getContentPane().add(p, BorderLayout.CENTER);
JPanel c = new JPanel(new GridLayout(0,1));
c.add(createControl("left length", 0, 0.9,
d -> p.setLeftLengthFactor(d)));
c.add(createControl("left width", 0, 0.9,
d -> p.setLeftWidthFactor(d)));
c.add(createControl("left angle", 0, Math.PI,
d -> p.setLeftAngleDelta(d)));
c.add(createControl("right length", 0, 0.9,
d -> p.setRightLengthFactor(d)));
c.add(createControl("right width", 0, 0.9,
d -> p.setRightWidthFactor(d)));
c.add(createControl("right angle", -Math.PI, 0,
d -> p.setRightAngleDelta(d)));
f.getContentPane().add(c, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static JPanel createControl(
String name, double min, double max, DoubleConsumer doubleConsumer)
{
JPanel p = new JPanel(new GridLayout(1,0));
p.add(new JLabel(name));
JSlider slider = new JSlider(0, 100, 0);
slider.addChangeListener(new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent e)
{
int value = slider.getValue();
double v = value / 100.0;
double d = min + v * (max - min);
doubleConsumer.accept(d);
}
});
p.add(slider);
return p;
}
}
class RecursiveTreeDrawingPanel extends JPanel
{
private double leftLengthFactor = 3.0 / 4.0;
private double leftWidthFactor = 3.0 / 4.0;
private double leftAngleDelta = Math.PI / 5.0;
private double rightLengthFactor = 2.0 / 3.0;
private double rightWidthFactor = 1.0 / 2.0;
private double rightAngleDelta = - Math.PI / 5.0;
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setColor(Color.BLACK);
g.fillRect(0,0,getWidth(),getHeight());
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Point2D start = new Point2D.Double(
getWidth() * 0.5,
getHeight() * 0.7);
g.setColor(Color.GRAY);
drawTree(g, start, 100.0, 2.0, 10.0, 0);
}
private void drawTree(Graphics2D g,
Point2D start, double length, double minLength,
double width, double alpha)
{
if (length < minLength)
{
return;
}
g.setStroke(new BasicStroke((float)width,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
Point2D end = new Point2D.Double(
start.getX() + Math.sin(alpha + Math.PI) * length,
start.getY() + Math.cos(alpha + Math.PI) * length);
g.draw(new Line2D.Double(start, end));
drawTree(g, end, length * leftLengthFactor, minLength,
width * leftWidthFactor, alpha + leftAngleDelta);
drawTree(g, end, length * rightLengthFactor, minLength,
width * rightWidthFactor, alpha + rightAngleDelta);
}
public void setLeftLengthFactor(double leftLengthFactor)
{
this.leftLengthFactor = leftLengthFactor;
repaint();
}
public void setLeftWidthFactor(double leftWidthFactor)
{
this.leftWidthFactor = leftWidthFactor;
repaint();
}
public void setLeftAngleDelta(double leftAngleDelta)
{
this.leftAngleDelta = leftAngleDelta;
repaint();
}
public void setRightLengthFactor(double rightLengthFactor)
{
this.rightLengthFactor = rightLengthFactor;
repaint();
}
public void setRightWidthFactor(double rightWidthFactor)
{
this.rightWidthFactor = rightWidthFactor;
repaint();
}
public void setRightAngleDelta(double rightAngleDelta)
{
this.rightAngleDelta = rightAngleDelta;
repaint();
}
}
关于java - 使用递归绘制树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30016085/
关于 B 树与 B+ 树,网上有一个比较经典的问题:为什么 MongoDb 使用 B 树,而 MySQL 索引使用 B+ 树? 但实际上 MongoDb 真的用的是 B 树吗?
如何将 R* Tree 实现为持久(基于磁盘)树?保存 R* 树索引或保存叶值的文件的体系结构是什么? 注意:此外,如何在这种持久性 R* 树中执行插入、更新和删除操作? 注意事项二:我已经实现了一个
目前,我正在努力用 Java 表示我用 SML 编写的 AST 树,这样我就可以随时用 Java 遍历它。 我想知道是否应该在 Java 中创建一个 Node 类,其中包含我想要表示的数据,以及一个数
我之前用过这个库http://www.cs.umd.edu/~mount/ANN/ .但是,它们不提供范围查询实现。我猜是否有一个 C++ 范围查询实现(圆形或矩形),用于查询二维数据。 谢谢。 最佳
在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择
书接上回,今天和大家一起动手来自己实现树。 相信通过前面的章节学习,大家已经明白树是什么了,今天我们主要针对二叉树,分别使用顺序存储和链式存储来实现树。 01、数组实现 我们在上一节中说过,
书节上回,我们接着聊二叉树,N叉树,以及树的存储。 01、满二叉树 如果一个二叉树,除最后一层节点外,每一层的节点数都达到最大值,即每个节点都有两个子节点,同时所有叶子节点都在最后一层,则这个
树是一种非线性数据结构,是以分支关系定义的层次结构,因此形态上和自然界中的倒挂的树很像,而数据结构中树根向上树叶向下。 什么是树? 01、定义 树是由n(n>=0)个元素节点组成的
操作系统的那棵“树” 今天从一颗 开始,我们看看如何从小树苗长成一颗苍天大树。 运转CPU CPU运转起来很简单,就是不断的从内存取值执行。 CPU没有好好运转 IO是个耗费时间的活,如果CPU在取值
我想为海洋生物学类(class)制作一个简单的系统发育树作为教育示例。我有一个具有分类等级的物种列表: Group <- c("Benthos","Benthos","Benthos","Be
我从这段代码中删除节点时遇到问题,如果我插入数字 12 并尝试删除它,它不会删除它,我尝试调试,似乎当它尝试删除时,它出错了树的。但是,如果我尝试删除它已经插入主节点的节点,它将删除它,或者我插入数字
B+ 树的叶节点链接在一起。将 B+ 树的指针结构视为有向图,它不是循环的。但是忽略指针的方向并将其视为链接在一起的无向叶节点会在图中创建循环。 在 Haskell 中,如何将叶子构造为父内部节点的子
我在 GWT 中使用树控件。我有一个自定义小部件,我将其添加为 TreeItem: Tree testTree = new Tree(); testTree.addItem(myWidget); 我想
它有点像混合树/链表结构。这是我定义结构的方式 struct node { nodeP sibling; nodeP child; nodeP parent; char
我编写了使用队列遍历树的代码,但是下面的出队函数生成错误,head = p->next 是否有问题?我不明白为什么这部分是错误的。 void Levelorder(void) { node *tmp,
例如,我想解析以下数组: var array1 = ["a.b.c.d", "a.e.f.g", "a.h", "a.i.j", "a.b.k"] 进入: var json1 = { "nod
问题 -> 给定一棵二叉树和一个和,确定该树是否具有从根到叶的路径,使得沿路径的所有值相加等于给定的和。 我的解决方案 -> public class Solution { public bo
我有一个创建 java 树的任务,它包含三列:运动名称、运动类别中的运动计数和上次更新。类似的东西显示在下面的图像上: 如您所见,有 4 种运动:水上运动、球类运动、跳伞运动和舞蹈运动。当我展开 sk
我想在 H2 数据库中实现 B+ Tree,但我想知道,B+ Tree 功能在 H2 数据库中可用吗? 最佳答案 H2 已经使用了 B+ 树(PageBtree 类)。 关于mysql - H2数据库
假设我们有 5 个字符串数组: String[] array1 = {"hello", "i", "cat"}; String[] array2 = {"hello", "i", "am"}; Str
我是一名优秀的程序员,十分优秀!