最近,我正在与Apache POI合作,我在旋转弯曲的连接器时遇到了一个问题,需要精确定位。我想将bent connector表示为形状之间的流动级别,我在可视化方面有一个问题,所以我的基本问题是在使用ooxml apache poi绘制形状连接器时,它被描述如下
我期待下面的结果,有人能提供一些建议来解决这个问题吗
ooxml和apache poi PPT
为了获得您想要的弯曲连接,默认的BENT_CONNECTOR_3
需要水平翻转,然后逆时针旋转90度。
下面的完整示例说明了这一点。注意代码中的注释。
import java.io.FileOutputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.*;
import org.openxmlformats.schemas.presentationml.x2006.main.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
public class CreatePPTXConnectorShapes {
private static XSLFConnectorShape createConnector(XSLFSlide slide, XSLFAutoShape shape1, XSLFAutoShape shape2) {
XSLFConnectorShape connector = slide.createConnector();
connector.setShapeType(ShapeType.BENT_CONNECTOR_3); // bent connector having one handle
connector.setAnchor(new Rectangle2D.Double( //connector is diagonal in a rectangle
shape1.getAnchor().getCenterX(), // top left x of that rectangle is center x position of shape1
shape1.getAnchor().getMaxY(), // top left y of that rectangle is bottom y of shape1
shape2.getAnchor().getCenterX()-shape1.getAnchor().getCenterX(), // width of that rectanle is center x of shape2 minus center x of shape1
shape2.getAnchor().getY()-shape1.getAnchor().getMaxY() // height of that rectanle is top y of shape2 minus bottom y of shape1
));
// the rectangle needs to be flipped horizontally as the default bent connector having one handle is like so:
// ----+
// |
// +----
connector.setFlipHorizontal(true);
// now it is like so:
// +----
// |
// ----+
// and needs to be rotated 90 deg counter-clockwise
connector.setRotation(-90.00);
// now it is like so:
// |
// +---+
// |
// now we fix the connecting points
CTConnector ctConnector = (CTConnector)connector.getXmlObject();
CTNonVisualConnectorProperties cx = ctConnector.getNvCxnSpPr().getCNvCxnSpPr();
CTConnection start = cx.addNewStCxn();
start.setId(shape1.getShapeId());
start.setIdx(2); // connecting point 2 is center of bottom edge
CTConnection end = cx.addNewEndCxn();
end.setId(shape2.getShapeId());
end.setIdx(0); // connecting point 0 is center of top edge
return connector;
}
public static void main(String[] args) throws Exception {
XMLSlideShow slideShow = new XMLSlideShow();
XSLFSlide slide = slideShow.createSlide();
XSLFAutoShape shape1 = slide.createAutoShape();
shape1.setShapeType(ShapeType.RECT);
shape1.setFillColor(Color.BLUE);
shape1.setAnchor(new Rectangle(50, 50, 150, 50));
XSLFAutoShape shape2 = slide.createAutoShape();
shape2.setShapeType(ShapeType.RECT);
shape2.setFillColor(Color.BLUE);
shape2.setAnchor(new Rectangle(150, 200, 150, 50));
// create connector
XSLFConnectorShape connector1 = createConnector(slide, shape1, shape2);
FileOutputStream out = new FileOutputStream("CreatePPTXConnectorShapes.pptx");
slideShow.write(out);
out.close();
}
}
它产生:
很明显,如果包含连接件的矩形(作为对角线)是正方形,那么旋转就很容易。这就是为什么上面的代码可以工作,并显示了主要原则。我将把它留在答案中,以免一开始就让它复杂化,并且有代码显示当包含连接线的矩形(作为对角线)不是正方形时的问题。
如果包含连接件作为对角线的矩形不是正方形,则需要考虑旋转时左上角位置和尺寸的变化来设置锚定。我们有TL1,旋转后所需的位置,可以根据形状的位置和尺寸来计算。我们需要TL0,旋转前的左上角点。对于尺寸,需要考虑旋转后宽度和高度的交换。
TL0*-------+
| . |
| . |
| . |
TL1*---------------------------+
| | . | |
h- - - - - - -+rp- - - - - -|
| | . | |
+-------------w-------------+
| . |
| . |
| . |
+-------+
we have TL1, which can get calculated from the shape position and dimension
TL1X, TL1Y, w: width, h: height
we need TL0, which is the top left point before rotating (rp = rotation point)
TL0X = TL1X + (w/2 - h/2) = TL1X + (w - h) / 2
TL0Y = TL1Y - (w/2 - h/2) = TL1Y - (w - h) / 2
width and height simply get swapped
如果形状2位于形状1的右下方,则以下操作应该有效。接头从形状1的下边缘中心到形状2的上边缘中心。
import java.io.FileOutputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.*;
import org.openxmlformats.schemas.presentationml.x2006.main.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
public class CreatePPTXConnectorShapes2 {
private static XSLFConnectorShape createConnector(XSLFSlide slide, XSLFAutoShape shape1, XSLFAutoShape shape2) {
XSLFConnectorShape connector = slide.createConnector();
// if shape2 is on the right below shape1; connector is from center of bottom edge of shape1 to center of top edge of shape2
if (shape2.getAnchor().getX() >= shape1.getAnchor().getCenterX() && shape2.getAnchor().getY() >= shape1.getAnchor().getMaxY()) {
connector.setShapeType(ShapeType.BENT_CONNECTOR_3); // bent connector having one handle
// the rectangle needs to be flipped horizontally as the default bent connector having one handle is like so:
// ----+
// |
// +----
connector.setFlipHorizontal(true);
// now it is like so:
// +----
// |
// ----+
// and needs to be rotated 90 deg counter-clockwise
connector.setRotation(-90.00);
// now it is like so:
// |
// |
// +---+
// |
// |
// set the anchor after rotating
//connector is diagonal in a rectangle
//before rotating it would be:
double topLeftX = shape1.getAnchor().getCenterX(); // top left x of that rectangle is center x position of shape1
double topLeftY = shape1.getAnchor().getMaxY(); // top left y of that rectangle is bottom y of shape1
double width = shape2.getAnchor().getCenterX()-shape1.getAnchor().getCenterX(); // width of that rectanle is center x of shape2 minus center x of shape1
double height = shape2.getAnchor().getY()-shape1.getAnchor().getMaxY(); // height of that rectanle is top y of shape2 minus bottom y of shape1
//considering the rotation it is:
topLeftX = topLeftX + (width - height) / 2;
topLeftY = topLeftY - (width - height) / 2;
double w = width;
width = height;
height = w;
connector.setAnchor(new Rectangle2D.Double(topLeftX, topLeftY, width, height));
// now it is like so:
// |
// +-------+
// |
// now we fix the connecting points
CTConnector ctConnector = (CTConnector)connector.getXmlObject();
CTNonVisualConnectorProperties cx = ctConnector.getNvCxnSpPr().getCNvCxnSpPr();
CTConnection start = cx.addNewStCxn();
start.setId(shape1.getShapeId());
start.setIdx(2); // connecting point 2 is center of bottom edge
CTConnection end = cx.addNewEndCxn();
end.setId(shape2.getShapeId());
end.setIdx(0); // connecting point 0 is center of top edge
}
return connector;
}
public static void main(String[] args) throws Exception {
XMLSlideShow slideShow = new XMLSlideShow();
XSLFSlide slide = slideShow.createSlide();
XSLFAutoShape shape1 = slide.createAutoShape();
shape1.setShapeType(ShapeType.RECT);
shape1.setFillColor(Color.BLUE);
shape1.setAnchor(new Rectangle(50, 50, 150, 50));
XSLFAutoShape shape2 = slide.createAutoShape();
shape2.setShapeType(ShapeType.RECT);
shape2.setFillColor(Color.BLUE);
shape2.setAnchor(new Rectangle(150, 200, 150, 50));
XSLFAutoShape shape3 = slide.createAutoShape();
shape3.setShapeType(ShapeType.RECT);
shape3.setFillColor(Color.BLUE);
shape3.setAnchor(new Rectangle(400, 200, 150, 50));
// create connectors
XSLFConnectorShape connector1 = createConnector(slide, shape1, shape2);
XSLFConnectorShape connector2 = createConnector(slide, shape1, shape3);
FileOutputStream out = new FileOutputStream("CreatePPTXConnectorShapes.pptx");
slideShow.write(out);
out.close();
}
}
它产生:
免责声明:正如我在这里的所有代码示例一样,这不是一个在生产环境中使用的适用于所有产品的解决方案,而只是一个展示原则的工作草案。为了创造一个可以有效使用的解决方案,你必须自己努力。
我正在尝试使用Surfaceview和canvas drawing在Android中创建自定义组件。这些组件可以通过触摸来调整大小和旋转。考虑创建一个图像视图,它的上、右、下和左边缘可通过触摸和拖动所需的边缘来缩放。我使用< code>RectF来保持组件的边界,对于旋转,我使用< code>canvas.rotate(angle,bounds.centerX()、bounds.centerY()
我如何制作
给定的是一个旋转的矩形,该矩形内接到另一个矩形中<两个矩形都有自己的坐标系 在该区域中 我对变换矩阵的尝试(setRotate() 如何计算P点相对于外矩形的位置? 提前感谢!
问题内容: 我想在Oracle 11g中旋转一个表。枢纽选项需要汇总。这是我的原始表: 旋转后,表格应如下所示: 现在,如您所见,分组应该在项目列上进行。无需折叠或计算值。只需旋转即可。那么,枢轴选择正确的事情了吗? 问题答案: 是的,我想是这样。使用汇总很容易进行这样的枢轴操作: 否则,您必须在max聚合内执行case语句。像这样: 这几乎和做。但我宁愿做在..
这是我当前的代码: 我一辈子都不知道如何旋转这个。我看了其他几个论坛,但没有其他机构讨论这个问题。 据我所知,没有办法旋转JPanel或JFrame,所以我运气不好吗? 这就是它现在的样子: 数字时钟 我想把它旋转90度。基本上是垂直的。 编辑:解决方案:
我目前正在用js尝试SVG路径,我想用一条曲线连接两点。以下是我目前的进展: CodePen版本在这里 看来我需要在路径中添加另一条曲线。 我还找到了这个工作的CodePen。