lab1总结:Turtle Graphics 和 Social Network

3.2Turtle Graphics

3.2.1 Problem 1: Clone and import

根据github网址加载zip,然后解压放到相应文件夹。在eclipse中f5刷新。或git中使用pull和clone命令下载到本地。init初始化本地仓库。可用add添加文件,commit加备注,push推送。

3.2.2 Problem 3: Turtle graphics and drawSquare

画一个方形:颜色设为黑色,设定边长sideLength,画一条sideLength长的线,然后转90°角,如此重复4次即可。

turtle.color(PenColor.BLACK);
for(int i=0; i<4; i++)
{
	turtle.forward(sideLength);
	turtle.turn(90);
}

3.2.3 Problem 5: Drawing polygons

根据多边形内角与边的关系:内角=(sides-2)*(180.0/sides)=180.0-360.0/sides.

public static double calculateRegularPolygonAngle(int sides) {//通过边数算内角
	double a = 180 -(360.0/sides);
	return a;
} 

由此,对于多边形,可先前进一个sideLength边长,然后转动内角的补角,循环边数次即可。
注:首先转270°的目的在于将绘制起始方向由上朝向左.

public static void drawRegularPolygon(Turtle turtle, int sides, int sideLength) {//绘制多边形
	turtle.turn(270);
	double a = 180.0 -calculateRegularPolygonAngle(sides);
	//a是内角的补角
	for(int i=0; i<sides; i++)
	{
		turtle.forward(sideLength);
		turtle.turn(a);
	}
}

例如六边形drawRegularPolygon(turtle,6,50):
六边形

3.2.4 Problem 6: Calculating Bearings

3.2.4.1calculateBearingToPoint()

给定初始点方向与上方的角度,初始点和目标点坐标,计算出顺时针达到目标点需要转过的角度。利用Math中的atan2函数,通过正切值计算出竖直时的转动角度,然后与给定初角度相减,计算出需要转过的角度。
注:要将弧度转化为角度,并把角度限制在0-359°范围内。

public static double calculateBearingToPoint(double currentBearing,int currentX, int currentY,int targetX, int targetY) {
	double angle = Math.atan2(targetX - currentX, targetY - currentY) * 180 / Math.PI - currentBearing;
	while(angle < 0)
		angle += 360;
	while(angle > 360)
		angle -= 360;
	return angle;
 }
3.2.4.2calculateBearings()

定义一个列表储存角度。函数输入为两个列表,分别储存点的横纵坐标。
循环取出两个list的同索引位的值为点坐标,调用calculateBearingToPoint(),初始角度0,计算角度add进角度list。
每循环一次更新初始角度,最后return角度的list。

public static List<Double> calculateBearings(List<Integer> xCoords, List<Integer> yCoords) {
	ArrayList <Double>Angle = new ArrayList<Double>();
	double currentAngle = 0;
	for(int i = 0;i < xCoords.size()-1; i++)
	{
		Angle.add(calculateBearingToPoint(currentAngle, xCoords.get(i), yCoords.get(i), xCoords.get(i+1), yCoords.get(i+1)));
		currentAngle = (currentAngle+Angle.get(i))%360.0;//更新角度
	}
	return Angle;
}

3.2.5 Problem 7: Convex Hulls

1.首先找到最左下角的点
2.以找到的点为基点,y轴正向为目前偏移角,开始依次找顺势针转角最小的点,记录这个点并将他加入到凸包集合中,以这次的偏向角累加上之前的角度度作为下一次的目前偏向角。
3.循环直到再次遇到最左下角为止退出。
计算偏向角函数:calculateBearingToPoint()。
部分代码:

public static Set<Point> convexHull(Set<Point> points) {
	Set<Point> shellPoint = new HashSet<Point>();
	Point minPoint = null;
	double nowBearing;
	double nextBearing;
	double preBearing;
	double nextLength;
	Point nowPoint;
	Point nextPoint = null;
	if (!points.isEmpty()) {
	// 元素小于3个时,必是凸包直接返回
		if (points.size() <= 3)
			return points;

		// 求最左下元素
		for (Point point : points) {
			if (minPoint == null) {
				minPoint = point;
				continue;
			}
			if (minPoint.x() > point.x())
				minPoint = point;
			else if (minPoint.x() == point.x()) {
				if (point.y() < minPoint.y())
					minPoint = point;
				}
			}
	......
		}
	......
}

3.2.6 Problem 8: Personal art

循环多次前进、旋转,设定颜色
例如:

public static void drawPersonalArt(Turtle turtle) {
     int i;
     for(i=0;i<400;i++)
     {
            switch (i%7) {
                case 0:turtle.color(PenColor.BLUE);break;
                case 1:turtle.color(PenColor.CYAN);break;
                case 2:turtle.color(PenColor.GRAY);break;
                case 3:turtle.color(PenColor.GREEN);break;
                case 4:turtle.color(PenColor.MAGENTA);break;
                case 5:turtle.color(PenColor.ORANGE);break;
                case 6:turtle.color(PenColor.PINK);break;
                case 7:turtle.color(PenColor.RED);break;
                case 8:turtle.color(PenColor.YELLOW);break;
                case 9:turtle.color(PenColor.BLACK);break;
                }
                turtle.turn(73);
                turtle.forward(i*7/5);
            }
     }

例子

3.3 Social Network

该任务要求设计一张社交网络图,基于连接人与人,并且能计算任意两人之间的联系情况。即数据结构图的建立与路径长。

3.3.1 设计/实现FriendshipGraph类

首先建立一个Person列表,用来储存人名。建立一个二维矩阵做图的邻接矩阵。建立Hashmap储存人名与此人在列表中的索引值这个键值对。

public ArrayList<Person> namelist = new ArrayList<Person>();//人名列表
public int edge[][] = new int[10000][10000];     //图的邻接矩阵
public HashMap<Person,Integer> name_location =new HashMap<Person,Integer>(); //人名与在列表中的索引键值对
3.3.1.1 addVertex(Person name)

如果人名列表里有人名与name相同,则给出错误提醒。否则,向列表添加名字,并且把这个名字-位置键值对放到map里。

namelist.add(name);
name_location.put(name, namelist.indexOf(name));//新加person键值对,人名-位置
3.3.1.2 addEdge(Person name1, Person name2)

利用键值对,通过名字获得其所在列表索引,对应与邻接矩阵值赋为1,代表两点相连。

public void addEdge(Person name1, Person name2) {//通过人名找到其邻接矩阵对应位置,然后设边长为1
	int x,y;
	x = name_location.get(name1);
	y = name_location.get(name2);
	edge[x][y] = 1;
}
3.3.1.3getDistance(Person name1, Person name2)

首先如果两人名相同,则返回0。不同,则用贪心算法(Dijkstra),把起点到所有点的距离都计算储存,找个最短的。然后遍历一遍,看以刚才距离最短的点为路的中转站会不会更近,不断更新循环。
部分代码:

for(int i=0; i<n-1; i++)//循环n-1次,每次都能加入一个点,最后每个点都已经加入
{
   w = 0;
   temp = 100;
   for(int j=0; j<n; j++)
   {
      if(!S[j]&&cost[j]<temp)
      {
         temp = cost[j];
         w = j;//
      }
  }
  S[w] = true;//遍历寻找一个当前最小的cost[j]即边长
  for(int v=0; v<n ;v++)
  {
    if(S[v]!=true)
    {
       sum = cost[w] + edge[w][v];
       if(sum<cost[v])
       {
          cost[v] = sum;
       }
    }
  }
}

3.3.2 设计/实现Person类

建立一个私有成员变量,设置构造函数,并且再建立一个getter方法。

public class Person {
	private String nameString;
	public String Getname()
	{
		return this.nameString;
	}
 
	public Person(String namString)
	{
		this.nameString = namString;
	}
}

3.3.3 设计/实现客户端代码main()

依据实验手册,初始化邻接矩阵,增加person对象和边,计算最短距离,与正确结果验证是否正确。

public static void main(String[] args) {
  FriendshipGraph graph = new FriendshipGraph();
  for(int i=0; i<graph.edge.length; i++)//初始化矩阵值为1000
  {
      for(int j=0; j<graph.edge.length; j++)
      {
           graph.edge[i][j] = 1000;
      }
  }
  Person rachel = new Person("Rachel");
  Person ross = new Person("Ross");
  Person ben = new Person("Ben");
  Person kramer = new Person("Kramer");
  graph.addVertex(rachel);
  graph.addVertex(ross);
  graph.addVertex(ben);
  graph.addVertex(kramer);
  graph.addEdge(rachel, ross);
  graph.addEdge(ross, rachel);
  graph.addEdge(ross, ben);
  graph.addEdge(ben, ross);
  System.out.println(graph.getDistance(rachel, ross));   //should print 1
  System.out.println(graph.getDistance(rachel, ben));    //should print 2
  System.out.println(graph.getDistance(rachel, rachel)); //should print 0
  System.out.println(graph.getDistance(rachel, kramer)); //should print -1
 }

添加的对象与边具体如下:
eg
运行结果:
结果
与should print的结果相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值