import org.apache.commons.lang3.tuple.*; interface Displayable { public void display(); } interface ToSVG { public String toSVG(); // points of the bounding rectangle public Integer minX(); public Integer minY(); public Integer maxX(); public Integer maxY(); // default methods using above four abstract methods default public Pair minPoint() { return Pair.of( this.minX(), this.minY() ); } default public Pair maxPoint() { return Pair.of( this.maxX(), this.maxY() ); } } import io.github.spencerpark.ijava.runtime.*; import org.apache.commons.lang3.tuple.*; abstract class Shape { // 인스턴스 변수 int width; // 양과 음의 정수값 모두 가능 int height; // 양과 음의 정수값 모두 가능 String fill; // 도형의 안쪽을 채우는 색깔 double opacity; // 도형을 그렸을 때 투명도 Shape(int width, int height, String fill, double opacity) { this.width = width; this.height = height; this.fill = fill; this.opacity = opacity; } // 추상 메소드 abstract double area(); // 넓이 계산 abstract String toSVGshape(Pair point); // SVG 기본 도형 태그 생성 @Override public String toString() { return super.toString() + String.format("(width=%d, height=%d, fill=%s, opacity=%f)", width, height, fill, opacity ); } void display() { // 이미지 형태로 보여주기 위한 메소드 Pair point = Pair.of( (width<0)? Math.abs(width) :0, (height<0)? Math.abs(height):0 ); String svgStr = String.format( "%s", Math.abs(width), Math.abs(height), this.toSVGshape(point) ); Display.display(svgStr,"text/html"); } } class RightTri extends Shape { RightTri(int width, int height, String fill, double opacity) { super(width, height, fill, opacity); } @Override double area() { return Math.abs(width * height) / 2; } // 삼각형 넓이공식에 맞게 @Override String toSVGshape(Pair point) { int x0 = point.getLeft(); int y0 = point.getRight(); return String.format("", x0,y0, fill, opacity) + String.format("", x0,y0, x0+width,y0, x0,y0+height, fill, opacity ); } } class Rectangle extends Shape { Rectangle(int width, int height, String fill, double opacity) { super(width, height, fill, opacity); } @Override double area() { return Math.abs(width * height); } // 직사각형 넓이공식에 맞게 @Override String toSVGshape(Pair point) { int x0 = point.getLeft(); int y0 = point.getRight(); return String.format("", x0,y0, fill, opacity) + String.format("", (width>0)? x0: x0+width, (height>0)? y0: y0+height, Math.abs(width), Math.abs(height), fill, opacity ); } } class ShapeObj2D implements Displayable, ToSVG { Pair point; Shape shape; ShapeObj2D(Pair point, Shape shape) { this.point = point; this.shape = shape; } @Override public String toString() { return super.toString() + String.format("( point=%s, shape=%s )", point.toString(), shape.toString() ); } // Displayable에서 오버라이드하라고 요구하는 메소드를 구현 @Override // 지금은 무조건 원점부터 1사분면만 그리고 있다고 생각하고 작성하고 있음 public void display() { // 이미지 형태로 보여주기 위한 메소드 String svgStr = String.format( "%s", maxX(), maxY(), this.toSVG() ); Display.display(svgStr,"text/html"); } // ToSVG에서 오버라이드하라고 요구하는 메소드들을 구현 @Override public String toSVG() { return shape.toSVGshape(point); } // points of the bounding rectangle @Override public Integer minX() { return Math.min(point.getLeft(), point.getLeft()+shape.width); } @Override public Integer minY() { return Math.min(point.getRight(), point.getRight()+shape.height); } @Override public Integer maxX() { return Math.max(point.getLeft(), point.getLeft()+shape.width); } @Override public Integer maxY() { return Math.max(point.getRight(), point.getRight()+shape.height); } /* // Trans2D에서 오버라이드하라고 요구하는 메소드들을 구현 */ } class GroupObj2D implements Displayable, ToSVG { ShapeObj2D [] objects; GroupObj2D(ShapeObj2D[] objects) { this.objects = objects; } /* @Override public String toString() { ... } */ /* // Displayable에서 오버라이드하라고 요구하는 메소드를 구현 */ /* // ToSVG에서 오버라이드하라고 요구하는 메소드들을 구현 */ /* // Trans2D에서 오버라이드하라고 요구하는 메소드들을 구현 */ }