mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 09:12:09 +10:00
Improved performance math calculations used to model "Twisted Wires"
This commit is contained in:
@@ -2898,6 +2898,10 @@
|
|||||||
<changeType>NEW_FEATURE</changeType>
|
<changeType>NEW_FEATURE</changeType>
|
||||||
<description>Added component-level caching that should speed up rendering dramatically. While in experimental phase, it will be exposed as "Enable Cache Boost" item in the "Config" menu so it can be turned off if it causes any issues</description>
|
<description>Added component-level caching that should speed up rendering dramatically. While in experimental phase, it will be exposed as "Enable Cache Boost" item in the "Config" menu so it can be turned off if it causes any issues</description>
|
||||||
</org.diylc.appframework.update.Change>
|
</org.diylc.appframework.update.Change>
|
||||||
|
<org.diylc.appframework.update.Change>
|
||||||
|
<changeType>IMPROVEMENT</changeType>
|
||||||
|
<description>Improved performance math calculations used to model "Twisted Wires"</description>
|
||||||
|
</org.diylc.appframework.update.Change>
|
||||||
<org.diylc.appframework.update.Change>
|
<org.diylc.appframework.update.Change>
|
||||||
<changeType>BUG_FIX</changeType>
|
<changeType>BUG_FIX</changeType>
|
||||||
<description>Older files that contain "Open Jack 1/4" components sometimes open with the jacks rotated the wrong way</description>
|
<description>Older files that contain "Open Jack 1/4" components sometimes open with the jacks rotated the wrong way</description>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import java.awt.geom.PathIterator;
|
|||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.diylc.common.LineStyle;
|
import org.diylc.common.LineStyle;
|
||||||
@@ -314,23 +315,26 @@ public class TwistedWire extends AbstractCurvedComponent<Void> implements IConti
|
|||||||
else
|
else
|
||||||
stroke = ObjectCache.getInstance().fetchBasicStroke(thickness);
|
stroke = ObjectCache.getInstance().fetchBasicStroke(thickness);
|
||||||
|
|
||||||
double segmentLength = thickness * 6;
|
double segmentLength = thickness * 6; // chosen empirically
|
||||||
|
|
||||||
// Convert to polygon
|
// Convert to polygon
|
||||||
List<Line2D> polygon = new ArrayList<Line2D>();
|
List<Line2D> polygon = new ArrayList<Line2D>();
|
||||||
for (CubicCurve2D curve : curves)
|
for (CubicCurve2D curve : curves)
|
||||||
polygon.addAll(split(curve, segmentLength));
|
polygon.addAll(split(curve, segmentLength));
|
||||||
|
|
||||||
List<Path2D> firstCurves = new ArrayList<Path2D>();
|
List<List<Path2D>> segments = new ArrayList<List<Path2D>>();
|
||||||
List<Path2D> secondCurves = new ArrayList<Path2D>();
|
segments.add(new ArrayList<Path2D>());
|
||||||
|
segments.add(new ArrayList<Path2D>());
|
||||||
|
|
||||||
Path2D current1 = new Path2D.Double();
|
Path2D[] currentPaths = new Path2D[2];
|
||||||
Path2D current2 = new Path2D.Double();
|
currentPaths[0] = new Path2D.Double();
|
||||||
double offset = thickness * 1.5;
|
currentPaths[1] = new Path2D.Double();
|
||||||
double rectSize = thickness * 3.5;
|
|
||||||
|
|
||||||
current1.moveTo(polygon.get(0).getX1(), polygon.get(0).getY1());
|
double offset = thickness * 1.5; // chosen empirically
|
||||||
current2.moveTo(polygon.get(0).getX1(), polygon.get(0).getY1());
|
double rectSize = thickness * 3.5; // chosen empirically
|
||||||
|
|
||||||
|
currentPaths[0].moveTo(polygon.get(0).getX1(), polygon.get(0).getY1());
|
||||||
|
currentPaths[1].moveTo(polygon.get(0).getX1(), polygon.get(0).getY1());
|
||||||
|
|
||||||
// create curved paths for each segment of the twisted pair
|
// create curved paths for each segment of the twisted pair
|
||||||
for (int i = 0; i < polygon.size(); i++) {
|
for (int i = 0; i < polygon.size(); i++) {
|
||||||
@@ -340,59 +344,74 @@ public class TwistedWire extends AbstractCurvedComponent<Void> implements IConti
|
|||||||
double theta = Math.atan2(line.getY2() - line.getY1(), line.getX2() - line.getX1());
|
double theta = Math.atan2(line.getY2() - line.getY1(), line.getX2() - line.getX1());
|
||||||
|
|
||||||
double sign = i % 2 == 0 ? 1 : -1;
|
double sign = i % 2 == 0 ? 1 : -1;
|
||||||
|
double[] thetas = new double[] { theta - sign * Math.PI / 2, theta + sign * Math.PI / 2};
|
||||||
|
|
||||||
double theta1 = theta - sign * Math.PI / 2;
|
int finalI = i;
|
||||||
double theta2 = theta + sign * Math.PI / 2;
|
|
||||||
|
|
||||||
current1.quadTo(centerX + offset * Math.cos(theta1),
|
// calculate curve segments in parallel
|
||||||
centerY + offset * Math.sin(theta1), line.getX2(), line.getY2());
|
Arrays.stream(new Integer[] { 0, 1 }).parallel().forEach((j) -> {
|
||||||
current2.quadTo(centerX + offset * Math.cos(theta2),
|
currentPaths[j].quadTo(centerX + offset * Math.cos(thetas[j]),
|
||||||
centerY + offset * Math.sin(theta2), line.getX2(), line.getY2());
|
centerY + offset * Math.sin(thetas[j]), line.getX2(), line.getY2());
|
||||||
|
if (finalI % 2 == 0 || finalI == polygon.size() - 1) {
|
||||||
if (i % 2 == 0 || i == polygon.size() - 1) {
|
segments.get(j).add(currentPaths[j]);
|
||||||
firstCurves.add(current1);
|
currentPaths[j] = new Path2D.Double();
|
||||||
current1 = new Path2D.Double();
|
currentPaths[j].moveTo(line.getX2(), line.getY2());
|
||||||
current1.moveTo(line.getX2(), line.getY2());
|
|
||||||
}
|
|
||||||
if (i % 2 == 1 || i == polygon.size() - 1) {
|
|
||||||
secondCurves.add(current2);
|
|
||||||
current2 = new Path2D.Double();
|
|
||||||
current2.moveTo(line.getX2(), line.getY2());
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert to Area
|
Area[] outputAreas = new Area[] { new Area(), new Area() };
|
||||||
for (Path2D p : firstCurves) {
|
|
||||||
firstLeadArea.add(new Area(stroke.createStrokedShape(p)));
|
// create stroked areas in parallel
|
||||||
}
|
Arrays.stream(new Integer[] { 0, 1 }).parallel().forEach((j) -> {
|
||||||
for (Path2D p : secondCurves) {
|
for (Path2D p : segments.get(j)) {
|
||||||
secondLeadArea.add(new Area(stroke.createStrokedShape(p)));
|
outputAreas[j].add(new Area(stroke.createStrokedShape(p)));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// at overlapping points, decide which lead goes on top and clear the overlapping area from the lead below
|
// at overlapping points, decide which lead goes on top and clear the overlapping area from the lead below
|
||||||
|
Integer[] idx = new Integer[polygon.size()];
|
||||||
for (int i = 0; i < polygon.size(); i++) {
|
for (int i = 0; i < polygon.size(); i++) {
|
||||||
|
idx[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arrays.stream(idx).parallel().forEach(i -> {
|
||||||
Line2D line = polygon.get(i);
|
Line2D line = polygon.get(i);
|
||||||
Area pointRect1 = new Area(new Rectangle2D.Double(line.getX1() - rectSize / 2, line.getY1() - rectSize / 2, rectSize, rectSize));
|
Area pointRect1 = new Area(new Rectangle2D.Double(line.getX1() - rectSize / 2,
|
||||||
|
line.getY1() - rectSize / 2, rectSize, rectSize));
|
||||||
|
|
||||||
if (i % 2 == 1) {
|
if (i % 2 == 1) {
|
||||||
pointRect1.intersect(firstLeadArea);
|
pointRect1.intersect(outputAreas[0]);
|
||||||
secondLeadArea.subtract(pointRect1);
|
synchronized (outputAreas[1]) {
|
||||||
|
outputAreas[1].subtract(pointRect1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pointRect1.intersect(secondLeadArea);
|
pointRect1.intersect(outputAreas[1]);
|
||||||
firstLeadArea.subtract(pointRect1);
|
synchronized (outputAreas[0]) {
|
||||||
|
outputAreas[0].subtract(pointRect1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == polygon.size() - 1) {
|
if (i == polygon.size() - 1) {
|
||||||
Area pointRect2 = new Area(new Rectangle2D.Double(line.getX2() - rectSize / 2, line.getY2() - rectSize / 2, rectSize, rectSize));
|
Area pointRect2 = new Area(new Rectangle2D.Double(line.getX2() - rectSize / 2,
|
||||||
|
line.getY2() - rectSize / 2, rectSize, rectSize));
|
||||||
if (i % 2 == 0) {
|
if (i % 2 == 0) {
|
||||||
pointRect2.intersect(firstLeadArea);
|
pointRect2.intersect(outputAreas[0]);
|
||||||
secondLeadArea.subtract(pointRect2);
|
synchronized (outputAreas[1]) {
|
||||||
|
outputAreas[1].subtract(pointRect2);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pointRect2.intersect(secondLeadArea);
|
pointRect2.intersect(outputAreas[1]);
|
||||||
firstLeadArea.subtract(pointRect2);
|
synchronized (outputAreas[0]) {
|
||||||
|
outputAreas[0].subtract(pointRect2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// dump to the output areas
|
||||||
|
firstLeadArea.add(outputAreas[0]);
|
||||||
|
secondLeadArea.add(outputAreas[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// splits a curve into a series of lines
|
// splits a curve into a series of lines
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ package org.diylc.swing.gui;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
@@ -108,6 +109,7 @@ public class MainFrame extends JFrame implements ISwingUI {
|
|||||||
public MainFrame() {
|
public MainFrame() {
|
||||||
super("DIYLC 3");
|
super("DIYLC 3");
|
||||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
|
setPreferredSize(new Dimension(1024, 700));
|
||||||
createBasePanels();
|
createBasePanels();
|
||||||
menuMap = new HashMap<String, JMenu>();
|
menuMap = new HashMap<String, JMenu>();
|
||||||
buttonGroupMap = new HashMap<String, ButtonGroup>();
|
buttonGroupMap = new HashMap<String, ButtonGroup>();
|
||||||
|
|||||||
Reference in New Issue
Block a user