现欲构造一个三角形求周长和面积完整的解决方案,下面是代码,有5个构造方法:
1.正三角形,构造参数1个边长;
2.直角三角形,构造参数2个直角边;
3.已知三边的任意三角形,构造参数3个边;
4.已知两相连两边及其夹角,构造参数2个边和1个夹角;
5.已知两角及其夹边, 构造参数2个角和1个夹边;
问题是:
1.构造方法3,4,5的参数都为3个,我采用把角的参数为float, 不知有什么缺陷。
2.有没有其他构造方法没写?
3.如果要写set方法, 如 setSides, 那么其他变量,角度、周长、面积也会跟着变,那该怎么处理呢?
4.是不是我的这个类根本的思路就不对?
/*
* Triangle.java
* @author Wenzee Yann, [email protected]
* @version 0.1000
* @since 2009.05.04
*/public class Triangle {
// 正三角形
public Triangle(double side) {
this.side1 = side;
this.side2 = side;
this.side3 = side;
this.angle1 = Math.PI / 3;
this.angle2 = Math.PI / 3;
this.angle3 = Math.PI / 3;
this.perimeter = 3 * side; // L = 3*a
this.area = Math.pow(side1, 2) * Math.sin(Math.PI / 3); //s = a*a*sin(π/3)
}
// 已知两直角边的直角三角形
public Triangle(double side1, double side2) {
this.side1 = side1;
this.side2 = side2;
this.side3 = Math.sqrt(side1 * side1 + side2 + side2);
this.angle1 = Math.atan(side1 / side2);
this.angle2 = Math.PI / 2 - this.angle1;
this.angle3 = Math.PI / 2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2;
}
/* 已知三边的任意三角形
* 余弦定理:a2=b2+c2-2bccosA, b2=a2+c2-2accosB, c2=a2+b2-2abcosC
* 三角形一边的平方等于另两边的平方和再减去这两边与夹角余弦的乘积的2倍
*/
public Triangle(double side1, double side2, double side3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
this.angle1 = Math.acos((this.side2 * this.side2
+ this.side3 + this.side3 - this.side1 * this.side1)
/ 2* this.side2 * this.side3); //余弦定理
this.angle2 = Math.acos((this.side1 * this.side1
+ this.side3 + this.side3 - this.side2 * this.side1)
/ 2* this.side1 * this.side3); //余弦定理
this.angle3 = Math.PI - this.side1 - this.side2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
/* 已知两相连两边及其夹角
* 正弦定理: a/sinA=b/sinB=c/sinC=2R, 其中R是三角形外接圆半径。
* 余弦定理:a2=b2+c2-2bccosA, b2=a2+c2-2accosB, c2=a2+b2-2abcosC
*/
public Triangle(double side1, double side2, float angle3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = Math.sqrt(this.side1 * this.side1
+ this.side2 * this.side2
- 2 * side1 * side2 * Math.cos(angle3)); //余弦定理
this.angle3 = angle3;
this.angle1 = Math.asin(this.side1 * Math.sin(this.angle3)
/ this.side3); //正弦定理
this.angle2 = Math.PI /2 - this.angle1 - this.angle2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
/* 已知两角及其夹边
* 正弦定理: a/sinA=b/sinB=c/sinC=2R, 其中R是三角形外接圆半径。
*/
public Triangle(double side1, float angle2, float angle3) {
this.angle1 = Math.PI - angle2 -angle3;
this.angle2 = angle2;
this.angle3 = angle3;
this.side1 = side1;
this.side2 = this.side1 * Math.sin(this.angle2)
/ Math.sin(this.angle1); //正弦定理
this.side3 = this.side1 * Math.sin(this.angle3)
/ Math.sin(this.angle1); //正弦定理
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
public double getSide1() {
return side1;
}
public double getSide2() {
return side2;
}
public double getSide3() {
return side3;
}
public double getAngle1() {
return angle1;
}
public double getAngle2() {
return angle2;
}
public double getAngle3() {
return angle3;
}
public double getPerimeter() {
return perimeter;
}
public double getArea() {
return area;
}
private double side1;
private double side2;
private double side3;
private double angle1; //side1对应角
private double angle2; //side2对应角
private double angle3; //side3对应角
private double perimeter; // 周长
private double area; // 面积
} // end class
1.正三角形,构造参数1个边长;
2.直角三角形,构造参数2个直角边;
3.已知三边的任意三角形,构造参数3个边;
4.已知两相连两边及其夹角,构造参数2个边和1个夹角;
5.已知两角及其夹边, 构造参数2个角和1个夹边;
问题是:
1.构造方法3,4,5的参数都为3个,我采用把角的参数为float, 不知有什么缺陷。
2.有没有其他构造方法没写?
3.如果要写set方法, 如 setSides, 那么其他变量,角度、周长、面积也会跟着变,那该怎么处理呢?
4.是不是我的这个类根本的思路就不对?
/*
* Triangle.java
* @author Wenzee Yann, [email protected]
* @version 0.1000
* @since 2009.05.04
*/public class Triangle {
// 正三角形
public Triangle(double side) {
this.side1 = side;
this.side2 = side;
this.side3 = side;
this.angle1 = Math.PI / 3;
this.angle2 = Math.PI / 3;
this.angle3 = Math.PI / 3;
this.perimeter = 3 * side; // L = 3*a
this.area = Math.pow(side1, 2) * Math.sin(Math.PI / 3); //s = a*a*sin(π/3)
}
// 已知两直角边的直角三角形
public Triangle(double side1, double side2) {
this.side1 = side1;
this.side2 = side2;
this.side3 = Math.sqrt(side1 * side1 + side2 + side2);
this.angle1 = Math.atan(side1 / side2);
this.angle2 = Math.PI / 2 - this.angle1;
this.angle3 = Math.PI / 2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2;
}
/* 已知三边的任意三角形
* 余弦定理:a2=b2+c2-2bccosA, b2=a2+c2-2accosB, c2=a2+b2-2abcosC
* 三角形一边的平方等于另两边的平方和再减去这两边与夹角余弦的乘积的2倍
*/
public Triangle(double side1, double side2, double side3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
this.angle1 = Math.acos((this.side2 * this.side2
+ this.side3 + this.side3 - this.side1 * this.side1)
/ 2* this.side2 * this.side3); //余弦定理
this.angle2 = Math.acos((this.side1 * this.side1
+ this.side3 + this.side3 - this.side2 * this.side1)
/ 2* this.side1 * this.side3); //余弦定理
this.angle3 = Math.PI - this.side1 - this.side2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
/* 已知两相连两边及其夹角
* 正弦定理: a/sinA=b/sinB=c/sinC=2R, 其中R是三角形外接圆半径。
* 余弦定理:a2=b2+c2-2bccosA, b2=a2+c2-2accosB, c2=a2+b2-2abcosC
*/
public Triangle(double side1, double side2, float angle3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = Math.sqrt(this.side1 * this.side1
+ this.side2 * this.side2
- 2 * side1 * side2 * Math.cos(angle3)); //余弦定理
this.angle3 = angle3;
this.angle1 = Math.asin(this.side1 * Math.sin(this.angle3)
/ this.side3); //正弦定理
this.angle2 = Math.PI /2 - this.angle1 - this.angle2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
/* 已知两角及其夹边
* 正弦定理: a/sinA=b/sinB=c/sinC=2R, 其中R是三角形外接圆半径。
*/
public Triangle(double side1, float angle2, float angle3) {
this.angle1 = Math.PI - angle2 -angle3;
this.angle2 = angle2;
this.angle3 = angle3;
this.side1 = side1;
this.side2 = this.side1 * Math.sin(this.angle2)
/ Math.sin(this.angle1); //正弦定理
this.side3 = this.side1 * Math.sin(this.angle3)
/ Math.sin(this.angle1); //正弦定理
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
public double getSide1() {
return side1;
}
public double getSide2() {
return side2;
}
public double getSide3() {
return side3;
}
public double getAngle1() {
return angle1;
}
public double getAngle2() {
return angle2;
}
public double getAngle3() {
return angle3;
}
public double getPerimeter() {
return perimeter;
}
public double getArea() {
return area;
}
private double side1;
private double side2;
private double side3;
private double angle1; //side1对应角
private double angle2; //side2对应角
private double angle3; //side3对应角
private double perimeter; // 周长
private double area; // 面积
} // end class
1.将度数也设为double,设想你new时传递参数是写90度方便,还是写90f度方便.
2.构造函数太独立了,各个构造函数没有联系性。比如说任意三边如果能判定是正三角就可以直接调用正三角的构造函数...
3.感觉这个类如果写get方法还好,如果写set方法有点麻烦,传进参数时得重新判定此参数和其他两个参数构成三角形的条件能不能成立,建议单独写个异常类抛出异常
4.这个类的重点主要是把握住传递进去的参数能不能构成三角形,还是建议单独写个判断是不是成立的异常类。
可以不用判断是什么三角形,直接求面积和周长package shape;public class Triangle {
/**
* point1,point2,point3为三角形的三点
*/
private Point point1;
private Point point2;
private Point point3;
public Triangle() {
super();
}
/**
* 构造方法
* @param point1 Point型
* @param point2 Point型
* @param point3 Point型
*/
public Triangle(Point point1, Point point2, Point point3) {
super();
this.point1 = point1;
this.point2 = point2;
this.point3 = point3;
}
public Point getPoint1() {
return point1;
}
public void setPoint1(Point point1) {
this.point1 = point1;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public Point getPoint3() {
return point3;
}
public void setPoint3(Point point3) {
this.point3 = point3;
}
/**
* 求三角形一条边A
* @return double型
*/
private double triangleA(){
return Math.hypot(point1.getCoordinate_x()-point2.getCoordinate_x(),point1.getCoordinate_y()-point2.getCoordinate_y());
}
/**
* 求三角形一条边B
* @return double型
*/
private double triangleB(){
return Math.hypot(point1.getCoordinate_x()-point3.getCoordinate_x(),point1.getCoordinate_y()-point3.getCoordinate_y());
}
/**
* 求三角形一条边C
* @return double型
*/
private double triangleC(){
return Math.hypot(point2.getCoordinate_x()-point3.getCoordinate_x(),point2.getCoordinate_y()-point3.getCoordinate_y());
}
/**
* 判断这三点是否可以构成三角形
* @return boolean型
*/
private boolean isTriangle(){
if(Math.abs(this.triangleA()+this.triangleB()) > this.triangleC() && Math.abs(this.triangleA()-this.triangleB()) < this.triangleC()){
return true;
}
else{
return false;
}
}
/**
* 如果可以构成三角形求三角形的面积
* 不可以构成三角形return 0;
* @return double型
*/
public double countArea(){
if(!this.isTriangle()){
return 0;
}
else{
double p = (this.triangleA() + this.triangleB() + this.triangleC())/2;
return Math.sqrt(p * (p - this.triangleA()) * (p - this.triangleB()) * (p - this.triangleC()));
}
}
public static void main(String[] args){
/* Point point1 = new Point(1,2);
Point point2 = new Point(1,3);
Point point3 = new Point(4,3);
Triangle triangle = new Triangle(point1,point2,point3);
System.out.println(triangle.countArea());
*/ Point point1 = new Point(0,0);
Point point2 = new Point(0,4);
Point point3 = new Point(3,0);
Triangle triangle = new Triangle(point1,point2,point3);
System.out.println(triangle.countArea());
}
}
已知三角形三边长为a,b,c.
周长的一半p = (a+b+c)/2
三角形面积=sqrt(p*(p-a)*(p-b)*(p-c))
风格属于典型的结构化编程产物。
功能不够灵活。你可以想象你的桌面上现在有一个“智能”的三角形“对象”的“实例”。
你可以改变它的某些属性,包括但不限于三条边的长度,三个角的角度,周长属性,面积属性。
每当你改变其中的某个属性,桌面上的三角形就会自动调整。海伦公式也好,正余弦定理也罢,编写一个auto_update过程,再只要GET/SET上述属性调用即可。
你的计算处理都在构造函数里完成了,还设置set方法有什么用?
我觉得楼主可以对整体设计改一下,用一个abstract类做父类,其余的五个做子类继承。还有最好把计算处理的代码从构造函数里分离出来另做一个函数。
正如你写的构造函数一样,可以只要三边,或者两边及夹角就好了(有了些条件,三角形就唯一确定了)。
这样的话,需要做的就是(以三边为例):
1. 写构造的时候要把不是以三边为参数的构造函数把三边计算出来
2. 写出getter时,不是取三边的话,都要用运算,如取周长就返回a+b+c
3. 写setter的时候,如是允许set角度,也是要把变化的边计算出来设回去...
2、成员的数量,一般只要保存3条边的长度就可以确定三角形的属性了,不需要保存角度信息。在数据量的应用中,可以用时间来换取空间。lz可以权衡取舍
3、如果是我来做这个class,我会做成只有getter,没有setter,三角形的属性,只能读,不能改,这样可以简化类的定义。可以参考字符串类的做法来实现属性的变化:obj=obj.modify(),函数复杂根据变化的内容,重新构造一个对象并返回,而不是直接在原对象上修改
<body><div>
asdfasf
</div>
</body>
</html>
已知三角形三边长为a,b,c.
周长的一半p = (a+b+c)/2
三角形面积=sqrt(p*(p-a)*(p-b)*(p-c))
这个方法更实用一点,当然前提是这个是三角形,要是连三角形都不是那么(a+b>=c||a-b<=c)
我认为在面向对象的意义上来说是说不过去的。可以定义一个 Line 类和 Angle 类分别表示边和角。
这个肯定有问题啊,方法重载需要有不同的参数
public static Triangle sideSideSide(double s, double s, double s) {..}
public static Triangle sideAngleSide(double s, double a, double s) {...}
public static Triangle angleSideAngle(double a, double s, double a) {...}
}//example
Triangle one = Triangle.sideSideSide(3,4,5);
改成
sideSideSide(double s1, double s2, double s3)
...
// 正三角形
public Triangle(double side) {
this.side1 = side;
this.side2 = side;
this.side3 = side;
this.angle1 = Math.PI / 3;
this.angle2 = Math.PI / 3;
this.angle3 = Math.PI / 3;
this.perimeter = 3 * side; // L = 3*a
this.area = Math.pow(side1, 2) * Math.sin(Math.PI / 3); //s = a*a*sin(π/3)
}
// 已知两直角边的直角三角形
public Triangle(double side1, double side2) {
this.side1 = side1;
this.side2 = side2;
this.side3 = Math.sqrt(side1 * side1 + side2 + side2);
this.angle1 = Math.atan(side1 / side2);
this.angle2 = Math.PI / 2 - this.angle1;
this.angle3 = Math.PI / 2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2;
} public Triangle(double side1, double side2, double side3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
this.angle1 = Math.acos((this.side2 * this.side2
+ this.side3 + this.side3 - this.side1 * this.side1)
/ 2* this.side2 * this.side3); //余弦定理
this.angle2 = Math.acos((this.side1 * this.side1
+ this.side3 + this.side3 - this.side2 * this.side1)
/ 2* this.side1 * this.side3); //余弦定理
this.angle3 = Math.PI - this.side1 - this.side2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
public Triangle(double side1, double side2, float angle3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = Math.sqrt(this.side1 * this.side1
+ this.side2 * this.side2
- 2 * side1 * side2 * Math.cos(angle3)); //余弦定理
this.angle3 = angle3;
this.angle1 = Math.asin(this.side1 * Math.sin(this.angle3)
/ this.side3); //正弦定理
this.angle2 = Math.PI /2 - this.angle1 - this.angle2;
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
/* 已知两角及其夹边
* 正弦定理: a/sinA=b/sinB=c/sinC=2R, 其中R是三角形外接圆半径。
*/
public Triangle(double side1, float angle2, float angle3) {
this.angle1 = Math.PI - angle2 -angle3;
this.angle2 = angle2;
this.angle3 = angle3;
this.side1 = side1;
this.side2 = this.side1 * Math.sin(this.angle2)
/ Math.sin(this.angle1); //正弦定理
this.side3 = this.side1 * Math.sin(this.angle3)
/ Math.sin(this.angle1); //正弦定理
this.perimeter = this.side1 + this.side2 + this.side3;
this.area = this.side1 * this.side2 * Math.cos(this.angle3);
}
public double getSide1() {
return side1;
}
public double getSide2() {
return side2;
}
public double getSide3() {
return side3;
}
public double getAngle1() {
return angle1;
}
public double getAngle2() {
return angle2;
}
public double getAngle3() {
return angle3;
}
public double getPerimeter() {
return perimeter;
}
public double getArea() {
return area;
}
}
}
double GetArea(double a, double b, double c, double R)
{
return a*b*c/4/R;
}
//已知三条边和内接圆半径,公式为s = pr
double GetArea(double a, double b, double c, double r)
{
return r*(a+b+c)/2;
}
//已知三角形三条边,求面积
double GetArea(doule a, double b, double c)
{
double p = (a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}//已知道三角形三个顶点的坐标struct Point
{
double x, y;
Point(double a = 0, double b = 0)
{
x = a; y = b;
}
};
double GetArea(Point p1, Point p2, Point p3)
{
double t = -p2.x*p1.y+p3.x*p1.y+p1.x*p2.y-p3.x*p2.y-p1.x*p3.y+p2.x*p3.y;
if(t < 0) t = -t;
return t/2;
}
WWW.BAIDU.COM
学习了!!!!!!
应该对我的Triangle类做以下处理:
1.首先应该搞清楚的是要写几个类,我的理解是这样的:
如果只是通过边长来改变Triangle,那么直需要写一个类;
如果有时候需要通过边长,有时候通过角度来改变Triangle,那么需要写几个类,
他们继承 abstract Triangle类。
5楼kkiieerr007观点。
2.所有不能写setter的实例域,及所有的计算变量都要去掉,而且不在constructor中求得,
通过setter获取器值。
21楼malligator的观点, 以及22楼rightyeah , 9楼xdop
3.3楼wanghailong0115的类是用来画图的,我现在还没到这一步,以后需要画图时,再来借用。
4.4楼sagegz说的海伦公式,我用上了,好用。
5.61楼的groovy2007的<<effective java>>显然对我这个业余的初学者来说,还要等待一段时间。
6.下面是我写的通过边长来改变Triangle,就写了一个类:/*
* Triangle.java
* @author [email protected], Wenzee Yann
* @version 0.100, @since 2009.05.04
*/
public class Triangle {
//等边三角形
public Triangle(double side) {
this.sideA = this.sideB = this.sideC = side;
}
//等腰三角形
public Triangle(double sideAB, double sideC) {
this.sideA = this.sideB = sideAB;
this.sideC = sideC;
}
//任意三边三角形
public Triangle(double sideA, double sideB, double sideC) {
this.sideA = sideA;
this.sideB = sideB;
this.sideC = sideC;
}
//两边及夹角
public Triangle(double sideA, double sideB, float angleC) {
this.sideA = sideA;
this.sideB = sideB;
// 余弦定理:a2=b2+c2-2bccosA, b2=a2+c2-2accosB, c2=a2+b2-2abcosC
this.sideC = Math.sqrt(sideA * sideA + sideB * sideB
- 2 * sideA * sideB * Math.cos(Math.toRadians(angleC)));
}
//两角及夹边
public Triangle(double sideA, float angleB, float angleC) {
this.sideA = sideA;
double angleA = 180 - angleB - angleC;
// 正弦定理:a/singA = b/sinB = c/sinC = 2R
this.sideB = (sideA / Math.sin(Math.toRadians(angleA)))
* Math.sin(Math.toRadians(angleB));
this.sideC = (sideA / Math.sin(Math.toRadians(angleA)))
* Math.sin(Math.toRadians(angleC));
}
public double getSideA(){
return sideA;
}
public double getSideB(){
return sideB;
}
public double getSideC(){
return sideC;
}
public double getAngleA() {
return Math.toDegrees(Math.acos((sideB * sideB + sideC * sideC - sideA * sideA )
/ (2 * sideB * sideC))); // 余弦定理
}
public double getAngleB() {
return Math.toDegrees(Math.acos((sideA * sideA + sideC * sideC - sideB * sideB)
/ (2 * sideA * sideC))); // 余弦定理
}
public double getAngleC() {
return Math.toDegrees(Math.acos((sideA * sideA + sideB * sideB - sideC * sideC)
/ (2 * sideA * sideB))); // 余弦定理
}
public double getPerimeter() {
return sideA +sideB + sideC;
}
public double getArea() {
double p = (sideA + sideB + sideC) / 2;
if ((sideA + sideB < sideC)
|| Math.abs((sideA - sideB)) > sideC)
return -1;
else
// 海伦公式 S =sqrt(P*(p-a)*(p-b)*(p-c)), p=(a+b+c)/2
return Math.sqrt(p * (p - sideA)
* (p - sideB) * (p - sideC));
}
public void setSideA(double sideA) {
this.sideA = sideA;
}
public void setSideB(double sideB) {
this.sideB = sideB;
}
public void setSideC(double sideC) {
this.sideC = sideC;
}
private double sideA;
private double sideB;
private double sideC;
}