package oripa.paint.creasepattern.tool; import java.util.ArrayList; import java.util.Collection; import oripa.value.OriLine; import oripa.value.OriPoint; public class RotatedLineFactory { /** * create copy of selected lines with a rotation around specified center point. * For a line l, this method creates rotatedLine(l, angleDeg * i) for i = 1 ... repetitionCount. * * @param cx x of center * @param cy y of center * @param angleDeg amount of rotation in degrees * @param repetitionCount * @param paperSize * * @return rotated lines */ public Collection<OriLine> createRotatedLines( double cx, double cy, double angleDeg, int repetitionCount, Collection<OriLine> creasePattern, double paperSize) { ArrayList<OriLine> rotatedLines = new ArrayList<OriLine>(); oripa.geom.RectangleClipper clipper = new oripa.geom.RectangleClipper( -paperSize / 2, -paperSize / 2, paperSize / 2, paperSize / 2); double angle = angleDeg * Math.PI / 180.0; for (int i = 0; i < repetitionCount; i++) { double angleRad = angle * (i + 1); for (OriLine l : creasePattern) { if (!l.selected) { continue; } OriPoint center = new OriPoint(cx, cy); OriPoint r0 = rotateAroundCenter(l.p0, center, angleRad); OriPoint r1 = rotateAroundCenter(l.p1, center, angleRad); OriLine rotatedLine = new OriLine(r0, r1, l.getTypeValue()); if (clipper.clip(rotatedLine)) { rotatedLines.add(rotatedLine); } } } return rotatedLines; } private OriPoint rotateAroundCenter(OriPoint p, OriPoint center, double angleRad) { OriPoint shiftedToCenter = new OriPoint(p.x - center.x, p.y - center.y); OriPoint rotated = rotate(shiftedToCenter, angleRad); rotated.add(center); return rotated; } private OriPoint rotate(OriPoint p, double angleRad) { OriPoint rotated = new OriPoint(); rotated.x = p.x * Math.cos(angleRad) - p.y * Math.sin(angleRad); rotated.y = p.x * Math.sin(angleRad) + p.y * Math.cos(angleRad); return rotated; } }