首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

三角形求周长和面积完整的解决方案,该怎么处理

2012-03-30 
三角形求周长和面积完整的解决方案现欲构造一个三角形求周长和面积完整的解决方案,下面是代码,有5个构造方

三角形求周长和面积完整的解决方案
现欲构造一个三角形求周长和面积完整的解决方案,下面是代码,有5个构造方法:
1.正三角形,构造参数1个边长;
2.直角三角形,构造参数2个直角边;
3.已知三边的任意三角形,构造参数3个边;
4.已知两相连两边及其夹角,构造参数2个边和1个夹角;
5.已知两角及其夹边, 构造参数2个角和1个夹边;
问题是:
1.构造方法3,4,5的参数都为3个,我采用把角的参数为float, 不知有什么缺陷。
2.有没有其他构造方法没写?
3.如果要写set方法, 如 setSides, 那么其他变量,角度、周长、面积也会跟着变,那该怎么处理呢?
4.是不是我的这个类根本的思路就不对?

Java code
 
/*
* Triangle.java
* @author Wenzee Yann, wenzee@gmail.com
* @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



[解决办法]
缺等腰三角形
[解决办法]
如果这个类是final的,我觉得整体思路上没什么问题.有几个细节再把握下
1.将度数也设为double,设想你new时传递参数是写90度方便,还是写90f度方便.
2.构造函数太独立了,各个构造函数没有联系性。比如说任意三边如果能判定是正三角就可以直接调用正三角的构造函数...
3.感觉这个类如果写get方法还好,如果写set方法有点麻烦,传进参数时得重新判定此参数和其他两个参数构成三角形的条件能不能成立,建议单独写个异常类抛出异常
4.这个类的重点主要是把握住传递进去的参数能不能构成三角形,还是建议单独写个判断是不是成立的异常类。
[解决办法]
这是我以前做的求三角形的面积 Point类是一个点的坐标类 
可以不用判断是什么三角形,直接求面积和周长

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))
[解决办法]
学习了!
[解决办法]

探讨
求面积用海轮公式:
已知三角形三边长为a,b,c.
周长的一半p = (a+b+c)/2
三角形面积=sqrt(p*(p-a)*(p-b)*(p-c))

[解决办法]
4.是不是我的这个类根本的思路就不对?

不能说不对,不过这个类看上去的确很“死板”。
风格属于典型的结构化编程产物。
功能不够灵活。

你可以想象你的桌面上现在有一个“智能”的三角形“对象”的“实例”。
你可以改变它的某些属性,包括但不限于三条边的长度,三个角的角度,周长属性,面积属性。
每当你改变其中的某个属性,桌面上的三角形就会自动调整。

海伦公式也好,正余弦定理也罢,编写一个auto_update过程,再只要GET/SET上述属性调用即可。
[解决办法]
貌似构造函数中有3个都是参数个数和类型完全相同……
[解决办法]
用海伦公式求面积最简单。
[解决办法]
这样全是全,可能用在教学三角形上挺好。实际用不必这样,根据实际应用可以更简单,如求面积海伦公式足以。
[解决办法]
其实针对楼主的这个问题,可以简单化。

比如归纳为已知三个边的长度,可以唯一确定一个三角形(三角形全等定理)。所以你唯一需要判断的就是这三个边能否确定一个三角形。可根据两边之和大于第三边;两边之后小于第三边来确定。

然后剩下的就是海伦定理求面积,已经三边相加求周长。


所以不用搞得那么复杂,管它什么等腰还是等边。
[解决办法]
float没有问题,边和角都是实数集合。
你的计算处理都在构造函数里完成了,还设置set方法有什么用?
我觉得楼主可以对整体设计改一下,用一个abstract类做父类,其余的五个做子类继承。还有最好把计算处理的代码从构造函数里分离出来另做一个函数。
[解决办法]
我觉得,如果你这个三角形是经常变的话,那么它的成员不需要那么多;
正如你写的构造函数一样,可以只要三边,或者两边及夹角就好了(有了些条件,三角形就唯一确定了)。
这样的话,需要做的就是(以三边为例):
1. 写构造的时候要把不是以三边为参数的构造函数把三边计算出来
2. 写出getter时,不是取三边的话,都要用运算,如取周长就返回a+b+c
3. 写setter的时候,如是允许set角度,也是要把变化的边计算出来设回去

...
[解决办法]
1、构造函数应该要能够检查不可能的条件,并抛出异常。这个前面已经有人说了
2、成员的数量,一般只要保存3条边的长度就可以确定三角形的属性了,不需要保存角度信息。在数据量的应用中,可以用时间来换取空间。lz可以权衡取舍
3、如果是我来做这个class,我会做成只有getter,没有setter,三角形的属性,只能读,不能改,这样可以简化类的定义。可以参考字符串类的做法来实现属性的变化:obj=obj.modify(),函数复杂根据变化的内容,重新构造一个对象并返回,而不是直接在原对象上修改
[解决办法]
谢谢楼主啊,这个刚好是我们今天的作业
[解决办法]
虽然目前对我没用,但是我还是收藏下
[解决办法]
求面积用海轮公式: 
已知三角形三边长为a,b,c. 
周长的一半p = (a+b+c)/2 
三角形面积=sqrt(p*(p-a)*(p-b)*(p-c)) 
 

这个方法更实用一点,当然前提是这个是三角形,要是连三角形都不是那么(a+b>=c||a-b<=c)
[解决办法]
探讨
4.是不是我的这个类根本的思路就不对?

不能说不对,不过这个类看上去的确很“死板”。
风格属于典型的结构化编程产物。
功能不够灵活。

你可以想象你的桌面上现在有一个“智能”的三角形“对象”的“实例”。
你可以改变它的某些属性,包括但不限于三条边的长度,三个角的角度,周长属性,面积属性。
每当你改变其中的某个属性,桌面上的三角形就会自动调整。

海伦公式也好,正余弦定理也罢,编写一个auto_…

[解决办法]
好 谢谢楼主分享
[解决办法]
1)缺少等腰三角形的构造方法;
2)其中2和4可以合并成一个方法,在方法内部判断这个角度的值;
3)3中应该加入判断三条边是否可以构成三角形;

------解决方案--------------------


已经是一个三角形了,怎么能 set 其中的一个参数呢?

不管把三边中的一边,还是三角中的一角设成其他的值,都无法再构成三角形了!
[解决办法]
边和角在数学意义上来说是不同的类型,而你只是仅仅采用 double 和 float 来分开说明,
我认为在面向对象的意义上来说是说不过去的。

可以定义一个 Line 类和 Angle 类分别表示边和角。
[解决办法]

探讨
其实针对楼主的这个问题,可以简单化。

比如归纳为已知三个边的长度,可以唯一确定一个三角形(三角形全等定理)。所以你唯一需要判断的就是这三个边能否确定一个三角形。可根据两边之和大于第三边;两边之后小于第三边来确定。

然后剩下的就是海伦定理求面积,已经三边相加求周长。


所以不用搞得那么复杂,管它什么等腰还是等边。

[解决办法]
建议你看下设计模式...
[解决办法]
思路正确,感觉编码有些问题,类的接口设计有够科学。没有考虑重用。
[解决办法]
构造方法3,4,5的参数都为3个,我采用把角的参数为float, 不知有什么缺陷。 
这个肯定有问题啊,方法重载需要有不同的参数
[解决办法]
收藏了,呵呵
[解决办法]
1.构造方法3,4,5的参数都为3个,我采用把角的参数为float, 不知有什么缺陷。

缺陷大大的。建议用静态方法取代构造函数,参见《effective java》第一条。

比如,可以这样写:
Java code
class Triangle {   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) {...}}//exampleTriangle one = Triangle.sideSideSide(3,4,5);
[解决办法]
探讨
1.构造方法3,4,5的参数都为3个,我采用把角的参数为float, 不知有什么缺陷。

缺陷大大的。建议用静态方法取代构造函数,参见《effective java》第一条。

比如,可以这样写:
Java codeclassTriangle {publicstaticTriangle sideSideSide(doubles,doubles,doubles) {..}publicstaticTriangle sideAngleSide(doubles,doublea,doubles) {...}publicstaticTriangle angleSideAngle(doublea,doubles,doublea) {...}
}//exam…

[解决办法]
*/

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;
}

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;
}
}
}
[解决办法]
看了这个公式 想了好长时间才想起来 学过 好久不用就忘记了。。。
[解决办法]
楼主c++提高空间很大
[解决办法]

C/C++ code
//已知三条边和外接圆半径,公式为s = a*b*c/(4*R)double GetArea(double a, double b, double c, double R){return a*b*c/4/R;}//已知三条边和内接圆半径,公式为s = prdouble 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;}
[解决办法]
楼主考虑的很全,在作更新时如果要考虑较率(大数据量的计算),应该这样.但是实现上就比较复杂了,如果将所有三角形的情况都有转换成海仑公式不计算,则太慢了.还分分开考虑好些!
[解决办法]
可以定义一个 Line 类和 Angle 类分别表示边和角。

这个想法好,可以考虑一下,也有很大的发展空间……
学习了!!!!!!

热点排行