Add rotary switches
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 204 KiB |
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 276 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 261 KiB After Width: | Height: | Size: 264 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 475 KiB After Width: | Height: | Size: 478 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 852 KiB After Width: | Height: | Size: 857 KiB |
|
Before Width: | Height: | Size: 379 KiB After Width: | Height: | Size: 371 KiB |
|
Before Width: | Height: | Size: 421 KiB After Width: | Height: | Size: 420 KiB |
|
Before Width: | Height: | Size: 446 KiB After Width: | Height: | Size: 445 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 160 KiB |
@@ -15,6 +15,10 @@ public class Angle {
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public double getValueRad() {
|
||||
return Math.toRadians(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
@@ -205,6 +205,9 @@ public class StringUtils {
|
||||
|
||||
public static void drawCenteredText(Graphics2D g2d, String text, double x, double y, HorizontalAlignment horizontalAlignment,
|
||||
VerticalAlignment verticalAlignment) {
|
||||
if (text == null)
|
||||
return;
|
||||
|
||||
String[] parts = text.split("\\<br\\>");
|
||||
if (parts.length > 1) {
|
||||
FontMetrics fontMetrics = g2d.getFontMetrics();
|
||||
|
||||
@@ -0,0 +1,693 @@
|
||||
/*
|
||||
*
|
||||
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
|
||||
*
|
||||
* This file is part of DIYLC.
|
||||
*
|
||||
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.diylc.components.electromechanical;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.awt.TwoCircleTangent;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractAngledComponent;
|
||||
import org.diylc.components.transform.AngledComponentTransformer;
|
||||
import org.diylc.core.Angle;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.ISwitch;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.presenter.AreaUtils;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Rotary Switch (Open)", author = "Branislav Stojkovic",
|
||||
category = "Electro-Mechanical", instanceNamePrefix = "SW",
|
||||
description = "Open rotary switch in several different switching configurations",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true,
|
||||
transformer = AngledComponentTransformer.class)
|
||||
public class RotarySwitchOpen extends AbstractAngledComponent<RotarySwitchOpenType>
|
||||
implements ISwitch {
|
||||
|
||||
private static final int ANGLE_OFFSET = -15;
|
||||
private static final int INNER_COMMON_ANGLE_OFFSET = -90;
|
||||
|
||||
public static Size LARGE_DIAMETER = new Size(25d, SizeUnit.mm);
|
||||
public static Size SMALL_DIAMETER = new Size(11d, SizeUnit.mm);
|
||||
public static Size SMALL_DISTANCE = new Size(20d, SizeUnit.mm);
|
||||
public static Size HOLE_DISTANCE = new Size(26d, SizeUnit.mm);
|
||||
public static Size BODY_HOLE_SIZE = new Size(3d, SizeUnit.mm);
|
||||
public static Size TERMINAL_HOLE_SIZE = new Size(1d, SizeUnit.mm);
|
||||
|
||||
private static final Size INNER_PIN_SPACING = new Size(20d, SizeUnit.mm);
|
||||
private static final Size OUTER_PIN_SPACING = new Size(30d, SizeUnit.mm);
|
||||
private static final Size INNER_COMMON_PIN_SPACING = new Size(11d, SizeUnit.mm);
|
||||
private static final Size OUTER_COMMON_PIN_SPACING = new Size(32d, SizeUnit.mm);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size PIN_DIAMETER = new Size(1d, SizeUnit.mm);
|
||||
private static Size PIN_WIDTH = new Size(0.08d, SizeUnit.in);
|
||||
private static Size PIN_THICKNESS = new Size(0.02d, SizeUnit.in);
|
||||
|
||||
private RotarySwitchOpenType configuration = RotarySwitchOpenType._2P6T;
|
||||
private Color color = PHENOLIC_DARK_COLOR;
|
||||
private SwitchTiming timing;
|
||||
private Color labelColor = Color.white;
|
||||
private Color pinColor = METAL_COLOR;
|
||||
private boolean showMarkers = true;
|
||||
private Angle angleOffset = Angle.of(ANGLE_OFFSET);
|
||||
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)};
|
||||
private double[] pointAngles;
|
||||
|
||||
public RotarySwitchOpen() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Type")
|
||||
public RotarySwitchOpenType getValue() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public void setValue(RotarySwitchOpenType configuration) {
|
||||
this.configuration = configuration;
|
||||
updateControlPoints();
|
||||
// Reset body shape
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateControlPoints() {
|
||||
Point2D firstPoint = controlPoints[0];
|
||||
int innerPinCount = 2 * configuration.getPositionCount();
|
||||
int commonPinCount = 2;
|
||||
int innerPinSpacing = getClosestOdd(INNER_PIN_SPACING.convertToPixels());
|
||||
int innerCommonPinSpacing = getClosestOdd(INNER_COMMON_PIN_SPACING.convertToPixels());
|
||||
int outerPinSpacing = getClosestOdd(OUTER_PIN_SPACING.convertToPixels());
|
||||
int outerCommonPinSpacing = getClosestOdd(OUTER_COMMON_PIN_SPACING.convertToPixels());
|
||||
|
||||
double angleIncrement = -Math.PI / 6;
|
||||
double commonAngleIncrement = -Math.PI;
|
||||
double angleOffset = this.angleOffset.getValueRad();
|
||||
double innerCommonAngleOffset = Math.toRadians(INNER_COMMON_ANGLE_OFFSET);
|
||||
double outerCommonAngleOffset = Math.toRadians(INNER_COMMON_ANGLE_OFFSET);
|
||||
double angleRad = Math.toRadians(getAngle().getValue());
|
||||
|
||||
controlPoints =
|
||||
new Point2D[1 + (innerPinCount + commonPinCount) * configuration.getPoleCount() / 2];
|
||||
pointAngles = new double[controlPoints.length];
|
||||
|
||||
controlPoints[0] = firstPoint;
|
||||
|
||||
double theta = angleOffset + angleRad;
|
||||
|
||||
for (int i = 0; i < configuration.getPositionCount(); i++) {
|
||||
controlPoints[i + 1] =
|
||||
new Point2D.Double(firstPoint.getX() + Math.cos(theta) * innerPinSpacing / 2,
|
||||
firstPoint.getY() + Math.sin(theta) * innerPinSpacing / 2);
|
||||
pointAngles[i + 1] = theta;
|
||||
theta += angleIncrement;
|
||||
}
|
||||
|
||||
theta = angleOffset + angleRad - Math.PI;
|
||||
|
||||
for (int i = 0; i < configuration.getPositionCount(); i++) {
|
||||
controlPoints[i + configuration.getPositionCount() + 1] =
|
||||
new Point2D.Double(firstPoint.getX() + Math.cos(theta) * innerPinSpacing / 2,
|
||||
firstPoint.getY() + Math.sin(theta) * innerPinSpacing / 2);
|
||||
pointAngles[i + configuration.getPositionCount() + 1] = theta;
|
||||
theta += angleIncrement;
|
||||
}
|
||||
|
||||
theta = innerCommonAngleOffset + angleRad;
|
||||
for (int i = 0; i < commonPinCount; i++) {
|
||||
controlPoints[i + innerPinCount + 1] =
|
||||
new Point2D.Double(firstPoint.getX() + Math.cos(theta) * innerCommonPinSpacing / 2,
|
||||
firstPoint.getY() + Math.sin(theta) * innerCommonPinSpacing / 2);
|
||||
pointAngles[i + innerPinCount + 1] = theta;
|
||||
theta += commonAngleIncrement;
|
||||
}
|
||||
|
||||
if (configuration.getNeedsSecondLevel()) {
|
||||
int secondLevelStart = commonPinCount + innerPinCount + 1;
|
||||
|
||||
theta = angleOffset + angleRad;
|
||||
|
||||
if (configuration.getPositionCount() == 5) {
|
||||
theta += angleIncrement;
|
||||
}
|
||||
|
||||
for (int i = 0; i < configuration.getPositionCount(); i++) {
|
||||
controlPoints[secondLevelStart + i] =
|
||||
new Point2D.Double(firstPoint.getX() + Math.cos(theta) * outerPinSpacing / 2,
|
||||
firstPoint.getY() + Math.sin(theta) * outerPinSpacing / 2);
|
||||
pointAngles[secondLevelStart + i] = theta;
|
||||
theta += angleIncrement;
|
||||
}
|
||||
|
||||
theta = angleOffset + angleRad - Math.PI;
|
||||
|
||||
for (int i = 0; i < configuration.getPositionCount(); i++) {
|
||||
controlPoints[secondLevelStart + i + configuration.getPositionCount()] =
|
||||
new Point2D.Double(firstPoint.getX() + Math.cos(theta) * outerPinSpacing / 2,
|
||||
firstPoint.getY() + Math.sin(theta) * outerPinSpacing / 2);
|
||||
pointAngles[secondLevelStart + i + configuration.getPositionCount()] = theta;
|
||||
theta += angleIncrement;
|
||||
}
|
||||
|
||||
theta = outerCommonAngleOffset + angleRad;
|
||||
for (int i = 0; i < commonPinCount; i++) {
|
||||
controlPoints[secondLevelStart + i + innerPinCount] =
|
||||
new Point2D.Double(firstPoint.getX() + Math.cos(theta) * outerCommonPinSpacing / 2,
|
||||
firstPoint.getY() + Math.sin(theta) * outerCommonPinSpacing / 2);
|
||||
pointAngles[secondLevelStart + i + innerPinCount] = theta;
|
||||
theta += commonAngleIncrement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
List<Area> bodyList = new ArrayList<Area>();
|
||||
int largeDiameter = getClosestOdd(LARGE_DIAMETER.convertToPixels());
|
||||
int smallDiameter = getClosestOdd(SMALL_DIAMETER.convertToPixels());
|
||||
int smallDistance = getClosestOdd(SMALL_DISTANCE.convertToPixels());
|
||||
int holeDistance = getClosestOdd(HOLE_DISTANCE.convertToPixels());
|
||||
int holeSize = getClosestOdd(BODY_HOLE_SIZE.convertToPixels());
|
||||
double x = controlPoints[0].getX();
|
||||
double y = controlPoints[0].getY();
|
||||
|
||||
TwoCircleTangent left = new TwoCircleTangent(new Point2D.Double(x, y),
|
||||
new Point2D.Double(x - smallDistance / 2, y), largeDiameter / 2, smallDiameter / 2);
|
||||
TwoCircleTangent right = new TwoCircleTangent(new Point2D.Double(x, y),
|
||||
new Point2D.Double(x + smallDistance / 2, y), largeDiameter / 2, smallDiameter / 2);
|
||||
|
||||
Area bodyArea = new Area(left);
|
||||
bodyArea.add(right);
|
||||
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(x - holeDistance / 2 - holeSize / 2,
|
||||
y - holeSize / 2, holeSize, holeSize)));
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(x + holeDistance / 2 - holeSize / 2,
|
||||
y - holeSize / 2, holeSize, holeSize)));
|
||||
|
||||
if (angle != 0) {
|
||||
AffineTransform tx = AffineTransform.getRotateInstance(Math.toRadians(angle), x, y);
|
||||
bodyArea.transform(tx);
|
||||
}
|
||||
|
||||
bodyList.add(bodyArea);
|
||||
|
||||
|
||||
int pinWidth = getClosestOdd(PIN_WIDTH.convertToPixels());
|
||||
int pinThickness = getClosestOdd(PIN_THICKNESS.convertToPixels());
|
||||
|
||||
// inner terminals and commons
|
||||
for (int i = 1; i < Math
|
||||
.ceil(controlPoints.length / (configuration.getNeedsSecondLevel() ? 2.0 : 1.0)); i++) {
|
||||
Shape pinShape;
|
||||
|
||||
pinShape = new Rectangle2D.Double(controlPoints[i].getX() - pinWidth / 2,
|
||||
controlPoints[i].getY() - pinThickness / 2, pinWidth, pinThickness);
|
||||
double theta = Math.atan2(controlPoints[i].getY() - controlPoints[0].getY(),
|
||||
controlPoints[i].getX() - controlPoints[0].getX()) + Math.PI / 2;
|
||||
Area rotatedPin = new Area(pinShape);
|
||||
rotatedPin.transform(AffineTransform.getRotateInstance(theta, controlPoints[i].getX(),
|
||||
controlPoints[i].getY()));
|
||||
|
||||
bodyList.add(rotatedPin);
|
||||
}
|
||||
|
||||
if (configuration.getNeedsSecondLevel()) {
|
||||
int innerPinCount = 2 * configuration.getPositionCount();
|
||||
int commonPinCount = 2;
|
||||
|
||||
double outerCommonAngleOffset = Math.toRadians(INNER_COMMON_ANGLE_OFFSET);
|
||||
int outerPinSpacing = getClosestOdd(OUTER_PIN_SPACING);
|
||||
int outerCommonPinSpacing = getClosestOdd(OUTER_COMMON_PIN_SPACING);
|
||||
int terminalHoleSize = getClosestOdd(TERMINAL_HOLE_SIZE);
|
||||
|
||||
int secondLevelStart = commonPinCount + innerPinCount + 1;
|
||||
|
||||
// outer terminals
|
||||
for (int i = 0; i < configuration.getPositionCount() * 2; i++) {
|
||||
Area terminalArea = new Area(new RoundRectangle2D.Double(x, y - pinWidth / 2,
|
||||
outerPinSpacing / 2 + pinWidth / 2, pinWidth, pinWidth / 2, pinWidth / 2));
|
||||
AffineTransform tx =
|
||||
AffineTransform.getRotateInstance(pointAngles[secondLevelStart + i], x, y);
|
||||
|
||||
terminalArea.transform(tx);
|
||||
terminalArea.subtract(bodyArea);
|
||||
terminalArea.subtract(new Area(new Ellipse2D.Double(
|
||||
controlPoints[secondLevelStart + i].getX() - terminalHoleSize / 2,
|
||||
controlPoints[secondLevelStart + i].getY() - terminalHoleSize / 2, terminalHoleSize,
|
||||
terminalHoleSize)));
|
||||
bodyList.add(terminalArea);
|
||||
}
|
||||
|
||||
// outer common terminals
|
||||
Area terminalArea =
|
||||
new Area(new RoundRectangle2D.Double(x - outerCommonPinSpacing / 2 - pinWidth / 2,
|
||||
y - pinWidth / 2, outerCommonPinSpacing + pinWidth, pinWidth, pinWidth / 2,
|
||||
pinWidth / 2));
|
||||
AffineTransform tx = AffineTransform.getRotateInstance(outerCommonAngleOffset, x, y);
|
||||
|
||||
terminalArea.transform(tx);
|
||||
terminalArea.subtract(bodyArea);
|
||||
terminalArea.subtract(new Area(new Ellipse2D.Double(
|
||||
controlPoints[controlPoints.length - 1].getX() - terminalHoleSize / 2,
|
||||
controlPoints[controlPoints.length - 1].getY() - terminalHoleSize / 2, terminalHoleSize,
|
||||
terminalHoleSize)));
|
||||
terminalArea.subtract(new Area(new Ellipse2D.Double(
|
||||
controlPoints[controlPoints.length - 2].getX() - terminalHoleSize / 2,
|
||||
controlPoints[controlPoints.length - 2].getY() - terminalHoleSize / 2, terminalHoleSize,
|
||||
terminalHoleSize)));
|
||||
|
||||
bodyList.addAll(AreaUtils.tryAreaBreakout(terminalArea));
|
||||
}
|
||||
|
||||
body = bodyList.toArray(new Shape[0]);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
|
||||
Shape[] body = getBody();
|
||||
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY,
|
||||
Constants.DEFAULT_THEME);
|
||||
finalBorderColor =
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: theme.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor =
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: getColor().darker();
|
||||
}
|
||||
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
||||
}
|
||||
|
||||
int commonPinCount = 2;
|
||||
int secondLevelStart = 2 * configuration.getPositionCount() + commonPinCount;
|
||||
|
||||
// Draw outer pins
|
||||
if (configuration.getNeedsSecondLevel()) {
|
||||
drawingObserver.startTrackingContinuityArea(true);
|
||||
for (int i = secondLevelStart; i < body.length; i++) {
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : pinColor);
|
||||
g2d.fill(body[i]);
|
||||
g2d.setColor(outlineMode ? finalBorderColor : pinColor.darker());
|
||||
g2d.draw(body[i]);
|
||||
}
|
||||
drawingObserver.stopTrackingContinuityArea();
|
||||
}
|
||||
|
||||
// Draw body
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : getColor());
|
||||
g2d.fill(body[0]);
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body[0]);
|
||||
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
// Draw pins
|
||||
for (int i = 1; i <= secondLevelStart; i++) {
|
||||
drawingObserver.startTrackingContinuityArea(true);
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : pinColor);
|
||||
g2d.fill(body[i]);
|
||||
drawingObserver.stopTrackingContinuityArea();
|
||||
if (!outlineMode) {
|
||||
g2d.setColor(outlineMode ? finalBorderColor : pinColor.darker());
|
||||
g2d.draw(body[i]);
|
||||
}
|
||||
}
|
||||
|
||||
g2d.setComposite(oldComposite);
|
||||
|
||||
// draw labels
|
||||
// StringUtils.drawCenteredText(g2d, name, controlPoints[0].getX(), controlPoints[0].getY(),
|
||||
// HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
|
||||
if (showMarkers) {
|
||||
g2d.setColor(labelColor);
|
||||
int innerPinSpacing = getClosestOdd(INNER_PIN_SPACING.convertToPixels());
|
||||
int innerCommonPinSpacing = getClosestOdd(INNER_COMMON_PIN_SPACING.convertToPixels());
|
||||
int outerPinCount = 2 * configuration.getPositionCount();
|
||||
double relativeLabelLocation = 0.85;
|
||||
Point2D firstPoint = controlPoints[0];
|
||||
for (int i = 0; i < outerPinCount; i++) {
|
||||
int x = (int) (firstPoint.getX()
|
||||
+ Math.cos(pointAngles[i + 1]) * relativeLabelLocation * innerPinSpacing / 2);
|
||||
int y = (int) (firstPoint.getY()
|
||||
+ Math.sin(pointAngles[i + 1]) * relativeLabelLocation * innerPinSpacing / 2);
|
||||
StringUtils.drawCenteredText(g2d, getControlPointNodeNameForRender(i + 1), x, y,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
relativeLabelLocation = 0.65;
|
||||
for (int i = 0; i < commonPinCount; i++) {
|
||||
int x = (int) (firstPoint.getX() + Math.cos(pointAngles[i + outerPinCount + 1])
|
||||
* relativeLabelLocation * innerCommonPinSpacing / 2);
|
||||
int y = (int) (firstPoint.getY() + Math.sin(pointAngles[i + outerPinCount + 1])
|
||||
* relativeLabelLocation * innerCommonPinSpacing / 2);
|
||||
StringUtils.drawCenteredText(g2d, getControlPointNodeNameForRender(i + outerPinCount + 1),
|
||||
x, y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
if (configuration.getNeedsSecondLevel()) {
|
||||
relativeLabelLocation = 0.90;
|
||||
int outerPinSpacing = getClosestOdd(OUTER_PIN_SPACING.convertToPixels());
|
||||
int outerCommonPinSpacing = getClosestOdd(OUTER_COMMON_PIN_SPACING.convertToPixels());
|
||||
|
||||
for (int i = 0; i < outerPinCount; i++) {
|
||||
int x = (int) (firstPoint.getX() + Math.cos(pointAngles[i + 1 + secondLevelStart])
|
||||
* relativeLabelLocation * outerPinSpacing / 2);
|
||||
int y = (int) (firstPoint.getY() + Math.sin(pointAngles[i + 1 + secondLevelStart])
|
||||
* relativeLabelLocation * outerPinSpacing / 2);
|
||||
StringUtils.drawCenteredText(g2d,
|
||||
getControlPointNodeNameForRender(i + 1 + secondLevelStart), x, y,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
// relativeLabelLocation = 0.90;
|
||||
for (int i = 0; i < commonPinCount; i++) {
|
||||
int x = (int) (firstPoint.getX()
|
||||
+ Math.cos(pointAngles[i + outerPinCount + 1 + secondLevelStart])
|
||||
* relativeLabelLocation * outerCommonPinSpacing / 2);
|
||||
int y = (int) (firstPoint.getY()
|
||||
+ Math.sin(pointAngles[i + outerPinCount + 1 + secondLevelStart])
|
||||
* relativeLabelLocation * outerCommonPinSpacing / 2);
|
||||
StringUtils.drawCenteredText(g2d,
|
||||
getControlPointNodeNameForRender(i + outerPinCount + 1 + secondLevelStart), x, y,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
int largeR = getClosestOdd(width * 3d / 8);
|
||||
int smallR = getClosestOdd(width / 6d);
|
||||
int hole = 4 * width / 32;
|
||||
|
||||
Area area = new TwoCircleTangent(new Point2D.Double(width * 0.5, height * 0.5),
|
||||
new Point2D.Double(width / 2, height / 8d), largeR, smallR);
|
||||
area.add((Area) new TwoCircleTangent(new Point2D.Double(width * 0.5, height * 0.5),
|
||||
new Point2D.Double(width / 2, height * 7 / 8d), largeR, smallR));
|
||||
|
||||
area.subtract(
|
||||
new Area(new Ellipse2D.Double((width - hole) / 2, height / 8 - hole / 2, hole, hole)));
|
||||
area.subtract(
|
||||
new Area(new Ellipse2D.Double((width - hole) / 2, height * 7 / 8 - hole / 2, hole, hole)));
|
||||
area.transform(AffineTransform.getRotateInstance(Math.PI / 4, width / 2, height / 2));
|
||||
g2d.setColor(color);
|
||||
g2d.fill(area);
|
||||
g2d.setColor(color.darker());
|
||||
g2d.draw(area);
|
||||
|
||||
int center = width / 2 + 1;
|
||||
int radius = width / 2 - 7;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int x = (int) (center + Math.cos(Math.PI / 10 + i * Math.PI / 5) * radius);
|
||||
int y = (int) (center + Math.sin(Math.PI / 10 + i * Math.PI / 5) * radius);
|
||||
g2d.setColor(pinColor);
|
||||
g2d.fillOval(x - 1, y - 1, 2, 2);
|
||||
g2d.setColor(pinColor.darker());
|
||||
g2d.drawOval(x - 1, y - 1, 2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point2D getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.NEVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point2D point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPointMoveFreely(int pointIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Label")
|
||||
public Color getLabelColor() {
|
||||
if (labelColor == null)
|
||||
labelColor = LABEL_COLOR;
|
||||
return labelColor;
|
||||
}
|
||||
|
||||
public void setLabelColor(Color labelColor) {
|
||||
this.labelColor = labelColor;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public SwitchTiming getTiming() {
|
||||
return timing;
|
||||
}
|
||||
|
||||
public void setTiming(SwitchTiming timing) {
|
||||
this.timing = timing;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Terminals")
|
||||
public Color getPinColor() {
|
||||
return pinColor;
|
||||
}
|
||||
|
||||
public void setPinColor(Color pinColor) {
|
||||
this.pinColor = pinColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Markers")
|
||||
public boolean getShowMarkers() {
|
||||
return showMarkers;
|
||||
}
|
||||
|
||||
public void setShowMarkers(boolean showMarkers) {
|
||||
this.showMarkers = showMarkers;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Angle Offset")
|
||||
public Angle getAngleOffset() {
|
||||
return angleOffset;
|
||||
}
|
||||
|
||||
public void setAngleOffset(Angle angleOffset) {
|
||||
this.angleOffset = angleOffset;
|
||||
updateControlPoints();
|
||||
// Reset body shape
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
Shape[] body = getBody();
|
||||
double minX = Double.MAX_VALUE;
|
||||
double maxX = Double.MIN_VALUE;
|
||||
double minY = Double.MAX_VALUE;
|
||||
double maxY = Double.MIN_VALUE;
|
||||
for (Shape shape : body) {
|
||||
Rectangle2D rect = shape.getBounds2D();
|
||||
minX = Math.min(rect.getMinX(), minX);
|
||||
maxX = Math.max(rect.getMaxX(), maxX);
|
||||
minY = Math.min(rect.getMinY(), minY);
|
||||
maxY = Math.max(rect.getMaxY(), maxY);
|
||||
}
|
||||
|
||||
int margin = 40; // to catch the pins that are outside the body, if needed
|
||||
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin,
|
||||
maxY - minY + 2 * margin);
|
||||
}
|
||||
|
||||
public static enum Mount {
|
||||
CHASSIS("Chassis"), PCB("PCB");
|
||||
|
||||
String name;
|
||||
|
||||
private Mount(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionCount() {
|
||||
return configuration.getPositionCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPositionName(int position) {
|
||||
return Integer.toString(position + 1);
|
||||
}
|
||||
|
||||
public String getControlPointNodeNameForRender(int index) {
|
||||
int commonPinCount = 2;
|
||||
int positionCount = configuration.getPositionCount();
|
||||
|
||||
if (index <= positionCount) {
|
||||
return Integer.toString(positionCount + 1 - index);
|
||||
}
|
||||
if (index <= 2 * positionCount) {
|
||||
return Integer.toString(2 * positionCount + 1 - index);
|
||||
}
|
||||
if (index <= 2 * positionCount + commonPinCount) {
|
||||
return Character.toString((char) ('A' + (index - 2 * positionCount - 1)));
|
||||
}
|
||||
int secondLevelStart = 2 * positionCount + commonPinCount;
|
||||
if (index <= positionCount + secondLevelStart) {
|
||||
return Integer.toString(positionCount + 1 - index + secondLevelStart);
|
||||
}
|
||||
if (index <= 2 * positionCount + secondLevelStart) {
|
||||
return Integer.toString(2 * positionCount + 1 - index + secondLevelStart);
|
||||
}
|
||||
if (index <= 2 * positionCount + commonPinCount + secondLevelStart) {
|
||||
return Character.toString((char) ('C' + (index - 2 * positionCount - 1 - secondLevelStart)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
int commonPinCount = 2;
|
||||
int positionCount = configuration.getPositionCount();
|
||||
|
||||
if (index <= positionCount) {
|
||||
return "A" + (positionCount + 1 - index);
|
||||
}
|
||||
if (index <= 2 * positionCount) {
|
||||
return "B" + (2 * positionCount + 1 - index);
|
||||
}
|
||||
if (index <= 2 * positionCount + commonPinCount) {
|
||||
return Character.toString((char) ('A' + (index - 2 * positionCount - 1)));
|
||||
}
|
||||
|
||||
int secondLevelStart = 2 * positionCount + commonPinCount;
|
||||
if (index <= positionCount + secondLevelStart) {
|
||||
return "C" + (positionCount + 1 - index + secondLevelStart);
|
||||
}
|
||||
if (index <= 2 * positionCount + secondLevelStart) {
|
||||
return "D" + (2 * positionCount + 1 - index + secondLevelStart);
|
||||
}
|
||||
if (index <= 2 * positionCount + commonPinCount + secondLevelStart) {
|
||||
return Character.toString((char) ('C' + (index - 2 * positionCount - 1 - secondLevelStart)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean arePointsConnected(int index1, int index2, int position) {
|
||||
if (index1 == 0)
|
||||
return false;
|
||||
|
||||
int commonPinCount = 2;
|
||||
int positionCount = configuration.getPositionCount();
|
||||
|
||||
if (index1 <= positionCount) {
|
||||
return index1 == positionCount - position && index2 == 2 * positionCount + 1;
|
||||
}
|
||||
if (index1 <= 2 * positionCount) {
|
||||
return index1 == 2 * positionCount - position && index2 == 2 * positionCount + 2;
|
||||
}
|
||||
if (index1 <= 2 * positionCount + commonPinCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (configuration.getNeedsSecondLevel()) {
|
||||
int secondLevelStart = 2 * positionCount + commonPinCount;
|
||||
if (index1 <= positionCount + secondLevelStart) {
|
||||
return index1 == secondLevelStart + positionCount - position
|
||||
&& index2 == 2 * positionCount + 1 + secondLevelStart;
|
||||
}
|
||||
if (index2 <= 2 * positionCount + secondLevelStart + commonPinCount) {
|
||||
return index1 == secondLevelStart + 2 * positionCount - position
|
||||
&& index2 == 2 * positionCount + 2 + secondLevelStart;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2018 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.components.electromechanical;
|
||||
|
||||
public enum RotarySwitchOpenType {
|
||||
_2P5T("2P5T", 2, 5, false), _2P6T("2P6T", 2, 6, false), _4P5T("4P5T", 4, 5, true), _4P6T("4P6T", 4, 6, true);
|
||||
|
||||
private String name;
|
||||
private int positionCount;
|
||||
private int poleCount;
|
||||
private boolean needsSecondLevel;
|
||||
|
||||
private RotarySwitchOpenType(String name, int poleCount, int positionCount, boolean needsSecondLevel) {
|
||||
this.name = name;
|
||||
this.poleCount = poleCount;
|
||||
this.positionCount = positionCount;
|
||||
this.needsSecondLevel = needsSecondLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getPoleCount() {
|
||||
return poleCount;
|
||||
}
|
||||
|
||||
public int getPositionCount() {
|
||||
return positionCount;
|
||||
}
|
||||
|
||||
public boolean getNeedsSecondLevel() {
|
||||
return needsSecondLevel;
|
||||
}
|
||||
}
|
||||
@@ -70,8 +70,7 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
|
||||
private static Color BODY_COLOR = Color.decode("#F7F7EF");
|
||||
private static Color LABEL_COLOR = BODY_COLOR.darker();
|
||||
public static Color PIN_COLOR = Color.decode("#00B2EE");
|
||||
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
|
||||
|
||||
public static Size PIN_DIAMETER = new Size(1d, SizeUnit.mm);
|
||||
private static Size PIN_WIDTH = new Size(0.08d, SizeUnit.in);
|
||||
private static Size PIN_THICKNESS = new Size(0.02d, SizeUnit.in);
|
||||
@@ -81,6 +80,7 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
private Mount mount = Mount.CHASSIS;
|
||||
private SwitchTiming timing;
|
||||
private Color labelColor = LABEL_COLOR;
|
||||
private Color pinColor = METAL_COLOR;
|
||||
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)};
|
||||
private double[] pointAngles;
|
||||
@@ -130,7 +130,7 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
controlPoints = new Point2D[outerPinCount + innerPinCount + 1];
|
||||
pointAngles = new double[controlPoints.length];
|
||||
|
||||
double theta = outerAngleOffset + Math.toRadians(getAngle().getValue());
|
||||
double theta = outerAngleOffset + getAngle().getValueRad();
|
||||
controlPoints[0] = firstPoint;
|
||||
|
||||
for (int i = 0; i < outerPinCount; i++) {
|
||||
@@ -141,7 +141,7 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
theta += outerAngleIncrement;
|
||||
}
|
||||
|
||||
theta = innerAngleOffset + Math.toRadians(getAngle().getValue());
|
||||
theta = innerAngleOffset + getAngle().getValueRad();
|
||||
for (int i = 0; i < innerPinCount; i++) {
|
||||
controlPoints[i + outerPinCount + 1] =
|
||||
new Point2D.Double(firstPoint.getX() + Math.cos(theta) * innerPinDiameter / 2,
|
||||
@@ -214,10 +214,13 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
rotatedPin.transform(AffineTransform.getRotateInstance(theta, controlPoints[i].getX(), controlPoints[i].getY()));
|
||||
pinShape = rotatedPin;
|
||||
}
|
||||
g2d.setColor(PIN_COLOR);
|
||||
g2d.fill(pinShape);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.setColor(pinColor);
|
||||
if (getMount() == Mount.CHASSIS)
|
||||
drawingObserver.startTrackingContinuityArea(true);
|
||||
g2d.fill(pinShape);
|
||||
drawingObserver.stopTrackingContinuityArea();
|
||||
g2d.setColor(pinColor.darker());
|
||||
g2d.draw(pinShape);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,17 +234,14 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
for (int i = 0; i < outerPinCount; i++) {
|
||||
int x = (int) (firstPoint.getX() + Math.cos(pointAngles[i + 1]) * relativeLabelLocation * outerPinDiameter / 2);
|
||||
int y = (int) (firstPoint.getY() + Math.sin(pointAngles[i + 1]) * relativeLabelLocation * outerPinDiameter / 2);
|
||||
StringUtils.drawCenteredText(g2d, Integer.toString(i + 1), x, y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
StringUtils.drawCenteredText(g2d, getControlPointNodeName(i + 1), x, y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
relativeLabelLocation = 0.65;
|
||||
int labelStep = 1;
|
||||
if (configuration.getPoleCount() == 2) {
|
||||
labelStep = 2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < innerPinCount; i++) {
|
||||
int x = (int) (firstPoint.getX() + Math.cos(pointAngles[i + outerPinCount + 1]) * relativeLabelLocation * innerPinDiameter / 2);
|
||||
int y = (int) (firstPoint.getY() + Math.sin(pointAngles[i + outerPinCount + 1]) * relativeLabelLocation * innerPinDiameter / 2);
|
||||
StringUtils.drawCenteredText(g2d, Character.toString((char)('A' + labelStep * i)), x, y,
|
||||
StringUtils.drawCenteredText(g2d, getControlPointNodeName(i + outerPinCount + 1), x, y,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
@@ -255,18 +255,18 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
|
||||
int commonX = (int) (width - 8 * width / 32d);
|
||||
int commonY = (int) (height - 8 * width / 32d);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
g2d.setColor(pinColor);
|
||||
g2d.fillOval(commonX - 1, commonY - 1, 3, 3);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.setColor(pinColor.darker());
|
||||
g2d.drawOval(commonX - 1, commonY - 1, 3, 3);
|
||||
|
||||
int radius = (int) (width - 6 * width / 32d);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int x = (int) (width + Math.cos(1.1 * Math.PI + i * Math.PI / 6) * radius);
|
||||
int y = (int) (height + Math.sin(1.1 * Math.PI + i * Math.PI / 6) * radius);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
g2d.setColor(pinColor);
|
||||
g2d.fillOval(x - 1, y - 1, 3, 3);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.setColor(pinColor.darker());
|
||||
g2d.drawOval(x - 1, y - 1, 3, 3);
|
||||
}
|
||||
|
||||
@@ -342,6 +342,15 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
this.timing = timing;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Terminals")
|
||||
public Color getPinColor() {
|
||||
return pinColor;
|
||||
}
|
||||
|
||||
public void setPinColor(Color pinColor) {
|
||||
this.pinColor = pinColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
Rectangle2D rect = getBody()[0].getBounds2D();
|
||||
@@ -373,6 +382,22 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
|
||||
public String getPositionName(int position) {
|
||||
return Integer.toString(position + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
int outerPinCount = 12;
|
||||
|
||||
if (index <= outerPinCount) {
|
||||
return Integer.toString(index);
|
||||
}
|
||||
|
||||
int labelStep = 1;
|
||||
if (configuration.getPoleCount() == 2) {
|
||||
labelStep = 2;
|
||||
}
|
||||
|
||||
return Character.toString((char)('A' + labelStep * (index - outerPinCount - 1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean arePointsConnected(int index1, int index2, int position) {
|
||||
|
||||
@@ -205,7 +205,7 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitchType> implem
|
||||
}
|
||||
body[1] = waferArea;
|
||||
|
||||
double theta = Math.toRadians(getAngle().getValue());
|
||||
double theta = getAngle().getValueRad();
|
||||
|
||||
Area terminalArea = new Area();
|
||||
Area commonTerminalArea = new Area();
|
||||
@@ -299,9 +299,9 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitchType> implem
|
||||
break;
|
||||
}
|
||||
|
||||
// Rotate if needed
|
||||
if (getAngle().getValue() != 0) {
|
||||
double theta = Math.toRadians(getAngle().getValue());
|
||||
// Rotate if needed
|
||||
double theta = getAngle().getValueRad();
|
||||
if (theta != 0) {
|
||||
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
|
||||
for (Point2D point : controlPoints) {
|
||||
rotation.transform(point, point);
|
||||
|
||||
@@ -188,7 +188,7 @@ public class SchallerMegaSwitch extends AbstractAngledComponent<String> implemen
|
||||
double y =
|
||||
(controlPoints[0].getY() + controlPoints[lastPointIdx].getY()) / 2 + getLabelDy() * 2.25;
|
||||
|
||||
double theta = Math.toRadians(getAngle().getValue()) - Math.PI / 2;
|
||||
double theta = getAngle().getValueRad() - Math.PI / 2;
|
||||
|
||||
if ((theta >= Math.PI / 2 && theta <= Math.PI) || (theta < -Math.PI / 2 && theta > -Math.PI)) {
|
||||
theta += Math.PI;
|
||||
@@ -248,7 +248,7 @@ public class SchallerMegaSwitch extends AbstractAngledComponent<String> implemen
|
||||
|
||||
body[1] = waferArea;
|
||||
|
||||
double theta = Math.toRadians(getAngle().getValue());
|
||||
double theta = getAngle().getValueRad();
|
||||
|
||||
Area terminalArea = new Area();
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
@@ -326,8 +326,8 @@ public class SchallerMegaSwitch extends AbstractAngledComponent<String> implemen
|
||||
}
|
||||
|
||||
// Rotate if needed
|
||||
if (getAngle().getValue() != 0) {
|
||||
double theta = Math.toRadians(getAngle().getValue());
|
||||
double theta = getAngle().getValueRad();
|
||||
if (theta != 0) {
|
||||
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
|
||||
for (Point2D point : controlPoints) {
|
||||
rotation.transform(point, point);
|
||||
@@ -343,7 +343,7 @@ public class SchallerMegaSwitch extends AbstractAngledComponent<String> implemen
|
||||
|
||||
private void updateLabelPositions() {
|
||||
double labelOffset = LABEL_OFFSET.convertToPixels();
|
||||
double theta = Math.toRadians(getAngle().getValue()) - Math.PI;
|
||||
double theta = getAngle().getValueRad() - Math.PI;
|
||||
labelDx = Math.cos(theta) * labelOffset;
|
||||
labelDy = Math.sin(theta) * labelOffset;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class Jumbo4PinTubeSocket extends AbstractAngledComponent<String> {
|
||||
double initialAngleOffset = angleIncrement / 2;
|
||||
|
||||
controlPoints = new Point2D[pinCount + 1];
|
||||
double theta = initialAngleOffset + Math.toRadians(getAngle().getValue());
|
||||
double theta = initialAngleOffset + getAngle().getValueRad();
|
||||
controlPoints[0] = firstPoint;
|
||||
for (int i = 0; i < pinCount; i++) {
|
||||
controlPoints[i + 1] =
|
||||
@@ -138,7 +138,7 @@ public class Jumbo4PinTubeSocket extends AbstractAngledComponent<String> {
|
||||
double mountingHoleSize = getClosestOdd(JUMBO_MOUNT_HOLE_SIZE.convertToPixels());
|
||||
double mountingHoleSpacing = getClosestOdd(JUMBO_MOUNT_HOLE_SPACING.convertToPixels());
|
||||
|
||||
double theta = Math.toRadians(getAngle().getValue());
|
||||
double theta = getAngle().getValueRad();
|
||||
int centerX = (int) (controlPoints[0].getX()
|
||||
+ Math.cos(theta) * (mountingHoleSpacing / 2 - mountingHoleSize / 2));
|
||||
int centerY = (int) (controlPoints[0].getY()
|
||||
@@ -159,7 +159,7 @@ public class Jumbo4PinTubeSocket extends AbstractAngledComponent<String> {
|
||||
|
||||
Area terminalArea = new Area();
|
||||
|
||||
double alpha = initialAngleOffset + Math.toRadians(getAngle().getValue());
|
||||
double alpha = initialAngleOffset + getAngle().getValueRad();
|
||||
double terminalLength = JUMBO_TERMINAL_LENGTH.convertToPixels();
|
||||
int terminalWidth = getClosestOdd(JUMBO_TERMINAL_WIDTH.convertToPixels());
|
||||
int terminalHoleDiameter = getClosestOdd(JUMBO_TERMINAL_HOLE_SIZE.convertToPixels());
|
||||
|
||||
@@ -167,7 +167,7 @@ public class TubeSocket extends AbstractAngledComponent<String> {
|
||||
double initialAngleOffset = hasEmptySpace ? angleIncrement : (angleIncrement / 2);
|
||||
|
||||
controlPoints = new Point2D[pinCount + 1];
|
||||
double theta = initialAngleOffset + Math.toRadians(getAngle().getValue());
|
||||
double theta = initialAngleOffset + getAngle().getValueRad();
|
||||
controlPoints[0] = firstPoint;
|
||||
for (int i = 0; i < pinCount; i++) {
|
||||
controlPoints[i + 1] =
|
||||
@@ -207,7 +207,7 @@ public class TubeSocket extends AbstractAngledComponent<String> {
|
||||
|
||||
if (base == Base.OCTAL) {
|
||||
int tickSize = getClosestOdd(OCTAL_TICK_SIZE.convertToPixels());
|
||||
double theta = Math.toRadians(getAngle().getValue());
|
||||
double theta = getAngle().getValueRad();
|
||||
int centerX = (int) (controlPoints[0].getX() + Math.cos(theta) * holeSize / 2);
|
||||
int centerY = (int) (controlPoints[0].getY() + Math.sin(theta) * holeSize / 2);
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(centerX - tickSize / 2, centerY - tickSize / 2, tickSize,
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.diylc.netlist;
|
||||
|
||||
import org.diylc.components.electromechanical.RotarySwitchOpen;
|
||||
import org.diylc.components.electromechanical.RotarySwitchOpenType;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RotarySwitchOpenTests extends AbstractSwitchTests {
|
||||
|
||||
@Test
|
||||
public void testRotarySwitch2P5T() {
|
||||
RotarySwitchOpen sw = new RotarySwitchOpen();
|
||||
|
||||
String[] validCombinations = new String[] {
|
||||
"0,5,11", "0,10,12",
|
||||
"1,4,11", "1,9,12",
|
||||
"2,3,11", "2,8,12",
|
||||
"3,2,11", "3,7,12",
|
||||
"4,1,11", "4,6,12"};
|
||||
|
||||
sw.setValue(RotarySwitchOpenType._2P5T);
|
||||
testSwitch(sw, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRotarySwitch2P6T() {
|
||||
RotarySwitchOpen sw = new RotarySwitchOpen();
|
||||
|
||||
String[] validCombinations = new String[] {
|
||||
"0,6,13", "0,12,14",
|
||||
"1,5,13", "1,11,14",
|
||||
"2,4,13", "2,10,14",
|
||||
"3,3,13", "3,9,14",
|
||||
"4,2,13", "4,8,14",
|
||||
"5,1,13", "5,7,14"};
|
||||
|
||||
sw.setValue(RotarySwitchOpenType._2P6T);
|
||||
testSwitch(sw, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRotarySwitch4P5T() {
|
||||
RotarySwitchOpen sw = new RotarySwitchOpen();
|
||||
|
||||
String[] validCombinations = new String[] {
|
||||
"0,5,11", "0,10,12", "0,17,23", "0,22,24",
|
||||
"1,4,11", "1,9,12", "1,16,23", "1,21,24",
|
||||
"2,3,11", "2,8,12", "2,15,23", "2,20,24",
|
||||
"3,2,11", "3,7,12", "3,14,23", "3,19,24",
|
||||
"4,1,11", "4,6,12", "4,13,23", "4,18,24"};
|
||||
|
||||
sw.setValue(RotarySwitchOpenType._4P5T);
|
||||
testSwitch(sw, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRotarySwitch4P6T() {
|
||||
RotarySwitchOpen sw = new RotarySwitchOpen();
|
||||
|
||||
String[] validCombinations = new String[] {
|
||||
"0,6,13", "0,12,14", "0,20,27", "0,26,28",
|
||||
"1,5,13", "1,11,14", "1,19,27", "1,25,28",
|
||||
"2,4,13", "2,10,14", "2,18,27", "2,24,28",
|
||||
"3,3,13", "3,9,14", "3,17,27", "3,23,28",
|
||||
"4,2,13", "4,8,14", "4,16,27", "4,22,28",
|
||||
"5,1,13", "5,7,14", "5,15,27", "5,21,28",};
|
||||
|
||||
sw.setValue(RotarySwitchOpenType._4P6T);
|
||||
testSwitch(sw, validCombinations);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import org.diylc.components.electromechanical.RotarySwitchSealed;
|
||||
import org.diylc.components.electromechanical.RotarySwitchSealedType;
|
||||
import org.junit.Test;
|
||||
|
||||
public abstract class RotarySwitchTests extends AbstractSwitchTests {
|
||||
public abstract class RotarySwitchSealedTests extends AbstractSwitchTests {
|
||||
|
||||
@Test
|
||||
public void testRotarySwitchSP12T() {
|
||||
@@ -25,7 +25,7 @@ public abstract class RotarySwitchTests extends AbstractSwitchTests {
|
||||
"0,1,13", "1,2,13", "2,3,13", "3,4,13", "4,5,13", "5,6,13",
|
||||
"0,7,14", "1,8,14", "2,9,14", "3,10,14", "4,11,14", "5,12,14"};
|
||||
|
||||
sw.setValue(RotarySwitchSealedType.DP6T);
|
||||
sw.setValue(RotarySwitchSealedType._2P6T);
|
||||
testSwitch(sw, validCombinations);
|
||||
}
|
||||
|
||||