[#1567] Implement rail button screw
This commit is contained in:
		
							parent
							
								
									8c150299bc
								
							
						
					
					
						commit
						58bd18dc84
					
				| @ -1077,9 +1077,10 @@ LaunchLugCfg.tab.Generalprop = General properties | |||||||
| ! RailButtonConfig | ! RailButtonConfig | ||||||
| RailBtnCfg.lbl.OuterDiam = Outer Diameter: | RailBtnCfg.lbl.OuterDiam = Outer Diameter: | ||||||
| RailBtnCfg.lbl.InnerDiam = Inner Diameter: | RailBtnCfg.lbl.InnerDiam = Inner Diameter: | ||||||
| RailBtnCfg.lbl.TotalHeight = Total Height: | RailBtnCfg.lbl.TotalHeight = Total Height (excl. screw): | ||||||
| RailBtnCfg.lbl.BaseHeight = Base Height: | RailBtnCfg.lbl.BaseHeight = Base Height: | ||||||
| RailBtnCfg.lbl.FlangeHeight = Flange Height: | RailBtnCfg.lbl.FlangeHeight = Flange Height: | ||||||
|  | RailBtnCfg.lbl.ScrewHeight = Screw Height: | ||||||
| RailBtnCfg.lbl.Angle = Rotation: | RailBtnCfg.lbl.Angle = Rotation: | ||||||
| RailBtnCfg.lbl.PosRelativeTo = Position relative to: | RailBtnCfg.lbl.PosRelativeTo = Position relative to: | ||||||
| RailBtnCfg.lbl.Plus = plus | RailBtnCfg.lbl.Plus = plus | ||||||
|  | |||||||
| @ -203,6 +203,8 @@ class DocumentConfig { | |||||||
| 				Reflection.findMethod( RailButton.class, "setBaseHeight", double.class))); | 				Reflection.findMethod( RailButton.class, "setBaseHeight", double.class))); | ||||||
| 		setters.put("RailButton:flangeheight",  new DoubleSetter( | 		setters.put("RailButton:flangeheight",  new DoubleSetter( | ||||||
| 				Reflection.findMethod( RailButton.class, "setFlangeHeight", double.class))); | 				Reflection.findMethod( RailButton.class, "setFlangeHeight", double.class))); | ||||||
|  | 		setters.put("RailButton:screwheight",  new DoubleSetter( | ||||||
|  | 				Reflection.findMethod( RailButton.class, "setScrewHeight", double.class))); | ||||||
| 		setters.put("RailButton:outerdiameter",  new DoubleSetter( | 		setters.put("RailButton:outerdiameter",  new DoubleSetter( | ||||||
| 				Reflection.findMethod( RailButton.class, "setOuterDiameter", double.class))); | 				Reflection.findMethod( RailButton.class, "setOuterDiameter", double.class))); | ||||||
| 		setters.put("RailButton:innerdiameter",  new DoubleSetter( | 		setters.put("RailButton:innerdiameter",  new DoubleSetter( | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ public class RailButtonSaver extends ExternalComponentSaver { | |||||||
| 		emitDouble( elements, "height", rb.getTotalHeight()); | 		emitDouble( elements, "height", rb.getTotalHeight()); | ||||||
| 		emitDouble( elements, "baseheight", rb.getBaseHeight()); | 		emitDouble( elements, "baseheight", rb.getBaseHeight()); | ||||||
| 		emitDouble( elements, "flangeheight", rb.getFlangeHeight()); | 		emitDouble( elements, "flangeheight", rb.getFlangeHeight()); | ||||||
|  | 		emitDouble( elements, "screwheight", rb.getScrewHeight()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	 | 	 | ||||||
|  | |||||||
| @ -131,7 +131,7 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl | |||||||
| 				ComponentPreset.DESCRIPTION, | 				ComponentPreset.DESCRIPTION, | ||||||
| 				ComponentPreset.BASE_HEIGHT, | 				ComponentPreset.BASE_HEIGHT, | ||||||
| 				ComponentPreset.FLANGE_HEIGHT, | 				ComponentPreset.FLANGE_HEIGHT, | ||||||
| 				//ComponentPreset.SCREW_HEIGHT,		// Add this later when we implement screws in the rail button | 				ComponentPreset.SCREW_HEIGHT, | ||||||
| 				ComponentPreset.HEIGHT, | 				ComponentPreset.HEIGHT, | ||||||
| 				ComponentPreset.INNER_DIAMETER, | 				ComponentPreset.INNER_DIAMETER, | ||||||
| 				ComponentPreset.OUTER_DIAMETER, | 				ComponentPreset.OUTER_DIAMETER, | ||||||
|  | |||||||
| @ -46,7 +46,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable, | |||||||
| 	protected double totalHeight_m; | 	protected double totalHeight_m; | ||||||
| 	protected double flangeHeight_m; | 	protected double flangeHeight_m; | ||||||
|  	protected double baseHeight_m; |  	protected double baseHeight_m; | ||||||
| 	protected double screwHeight_m;		// This has no effect at the moment; is for future use. | 	protected double screwHeight_m; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	private double radialDistance_m=0; | 	private double radialDistance_m=0; | ||||||
| @ -208,19 +208,6 @@ public class RailButton extends ExternalComponent implements AnglePositionable, | |||||||
| 		fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); | 		fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setTotalHeight(double newHeight ) { |  | ||||||
| 		for (RocketComponent listener : configListeners) { |  | ||||||
| 			if (listener instanceof RailButton) { |  | ||||||
| 				((RailButton) listener).setTotalHeight(newHeight); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		this.totalHeight_m = Math.max(newHeight, this.flangeHeight_m + this.baseHeight_m); |  | ||||||
| 
 |  | ||||||
| 		clearPreset(); |  | ||||||
| 		fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public boolean isAerodynamic(){ | 	public boolean isAerodynamic(){ | ||||||
| 		// TODO: implement aerodynamics | 		// TODO: implement aerodynamics | ||||||
| @ -270,8 +257,8 @@ public class RailButton extends ExternalComponent implements AnglePositionable, | |||||||
| 	public BoundingBox getInstanceBoundingBox(){ | 	public BoundingBox getInstanceBoundingBox(){ | ||||||
| 		BoundingBox instanceBounds = new BoundingBox(); | 		BoundingBox instanceBounds = new BoundingBox(); | ||||||
| 		 | 		 | ||||||
| 		instanceBounds.update(new Coordinate(0, this.totalHeight_m, 0)); | 		instanceBounds.update(new Coordinate(0, this.totalHeight_m + this.screwHeight_m, 0)); | ||||||
| 		instanceBounds.update(new Coordinate(0, -this.totalHeight_m, 0)); | 		instanceBounds.update(new Coordinate(0, -this.totalHeight_m - this.screwHeight_m, 0)); | ||||||
| 		 | 		 | ||||||
| 		final double r = this.getOuterDiameter() / 2; | 		final double r = this.getOuterDiameter() / 2; | ||||||
| 		instanceBounds.update(new Coordinate(r, 0, r)); | 		instanceBounds.update(new Coordinate(r, 0, r)); | ||||||
| @ -322,9 +309,8 @@ public class RailButton extends ExternalComponent implements AnglePositionable, | |||||||
| 		final double volOuter = Math.PI*Math.pow( outerDiameter_m/2, 2)*flangeHeight_m; | 		final double volOuter = Math.PI*Math.pow( outerDiameter_m/2, 2)*flangeHeight_m; | ||||||
| 		final double volInner = Math.PI*Math.pow( innerDiameter_m/2, 2)*getInnerHeight(); | 		final double volInner = Math.PI*Math.pow( innerDiameter_m/2, 2)*getInnerHeight(); | ||||||
| 		final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)* baseHeight_m; | 		final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)* baseHeight_m; | ||||||
| 		return (volOuter+ | 		final double volScrew = 2f/3 * Math.PI * MathUtil.pow2(outerDiameter_m/2) * screwHeight_m; | ||||||
| 				volInner+ | 		return volOuter + volInner + volStandoff + volScrew; | ||||||
| 				volStandoff); |  | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	@Override | 	@Override | ||||||
| @ -386,13 +372,18 @@ public class RailButton extends ExternalComponent implements AnglePositionable, | |||||||
| 	@Override | 	@Override | ||||||
| 	public Coordinate getComponentCG() { | 	public Coordinate getComponentCG() { | ||||||
| 		// Math.PI and density are assumed constant through calculation, and thus may be factored out. | 		// Math.PI and density are assumed constant through calculation, and thus may be factored out. | ||||||
| 		final double volumeBase = Math.pow(outerDiameter_m / 2, 2) * this.baseHeight_m; | 		final double massBase = Math.pow(outerDiameter_m / 2, 2) * this.baseHeight_m; | ||||||
| 		final double volumeFlange = Math.pow(outerDiameter_m / 2, 2)* this.flangeHeight_m; | 		final double massInner = Math.pow(innerDiameter_m / 2, 2)* getInnerHeight(); | ||||||
| 		final double volumeInner = Math.pow(innerDiameter_m / 2, 2)* getInnerHeight(); | 		final double massFlange = Math.pow(outerDiameter_m / 2, 2)* this.flangeHeight_m; | ||||||
| 		final double totalVolume = volumeFlange + volumeInner + volumeBase; | 		final double massScrew = 2f/3 * MathUtil.pow2(outerDiameter_m/2) * screwHeight_m; | ||||||
| 		final double heightCM = (volumeFlange*( this.totalHeight_m-getFlangeHeight()/2) + volumeInner*( this.baseHeight_m + this.getInnerHeight()/2) + volumeBase*(this.baseHeight_m /2))/totalVolume; | 		final double totalMass = massFlange + massInner + massBase + massScrew; | ||||||
|  | 		final double baseCM = this.baseHeight_m /2; | ||||||
|  | 		final double innerCM = this.baseHeight_m + this.getInnerHeight()/2; | ||||||
|  | 		final double flangeCM = this.totalHeight_m - getFlangeHeight()/2; | ||||||
|  | 		final double screwCM = this.totalHeight_m + 4 * this.screwHeight_m / (3 * Math.PI); | ||||||
|  | 		final double heightCM = (massBase*baseCM + massInner*innerCM + massFlange*flangeCM + massScrew*screwCM)/totalMass; | ||||||
| 
 | 
 | ||||||
| 		if( heightCM > this.totalHeight_m ){ | 		if (heightCM > this.totalHeight_m + this.screwHeight_m) { | ||||||
| 			throw new BugException(" bug found while computing the CG of a RailButton: "+this.getName()+"\n height of CG: "+heightCM); | 			throw new BugException(" bug found while computing the CG of a RailButton: "+this.getName()+"\n height of CG: "+heightCM); | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
| @ -450,6 +441,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable, | |||||||
| 		if (preset.has(ComponentPreset.BASE_HEIGHT)) { | 		if (preset.has(ComponentPreset.BASE_HEIGHT)) { | ||||||
| 			this.baseHeight_m = preset.get(ComponentPreset.BASE_HEIGHT); | 			this.baseHeight_m = preset.get(ComponentPreset.BASE_HEIGHT); | ||||||
| 		} | 		} | ||||||
|  | 		if (preset.has(ComponentPreset.SCREW_HEIGHT)) { | ||||||
|  | 			this.screwHeight_m = preset.get(ComponentPreset.SCREW_HEIGHT); | ||||||
|  | 		} | ||||||
| 		if (preset.has(ComponentPreset.CD) && preset.get(ComponentPreset.CD) > 0) { | 		if (preset.has(ComponentPreset.CD) && preset.get(ComponentPreset.CD) > 0) { | ||||||
| 			setCDOverridden(true); | 			setCDOverridden(true); | ||||||
| 			setOverrideCD(preset.get(ComponentPreset.CD)); | 			setOverrideCD(preset.get(ComponentPreset.CD)); | ||||||
|  | |||||||
| @ -100,6 +100,16 @@ public class RailButtonConfig extends RocketComponentConfig { | |||||||
| 			panel.add(new BasicSlider(heightModel.getSliderModel(new DoubleModel(component, "MinTotalHeight", UnitGroup.UNITS_LENGTH), 0.02)), | 			panel.add(new BasicSlider(heightModel.getSliderModel(new DoubleModel(component, "MinTotalHeight", UnitGroup.UNITS_LENGTH), 0.02)), | ||||||
| 					"w 100lp, wrap para"); | 					"w 100lp, wrap para"); | ||||||
| 		} | 		} | ||||||
|  | 		{ //// Screw height | ||||||
|  | 			panel.add(new JLabel(trans.get("RailBtnCfg.lbl.ScrewHeight"))); | ||||||
|  | 			DoubleModel heightModel = new DoubleModel(component, "ScrewHeight", UnitGroup.UNITS_LENGTH, 0); | ||||||
|  | 			JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel()); | ||||||
|  | 			heightSpinner.setEditor(new SpinnerEditor(heightSpinner)); | ||||||
|  | 			panel.add(heightSpinner, "growx"); | ||||||
|  | 			order.add(((SpinnerEditor) heightSpinner.getEditor()).getTextField()); | ||||||
|  | 			panel.add(new UnitSelector(heightModel), "growx"); | ||||||
|  | 			panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.02)), "w 100lp, wrap para"); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		{ //// Angular Position: | 		{ //// Angular Position: | ||||||
| 			panel.add(new JLabel(trans.get("RailBtnCfg.lbl.Angle"))); | 			panel.add(new JLabel(trans.get("RailBtnCfg.lbl.Angle"))); | ||||||
|  | |||||||
| @ -29,6 +29,8 @@ import net.sf.openrocket.rocketcomponent.TubeFinSet; | |||||||
| import net.sf.openrocket.util.Coordinate; | import net.sf.openrocket.util.Coordinate; | ||||||
| import net.sf.openrocket.util.Transformation; | import net.sf.openrocket.util.Transformation; | ||||||
| 
 | 
 | ||||||
|  | import static com.jogamp.opengl.GL2ES3.GL_QUADS; | ||||||
|  | 
 | ||||||
| /* | /* | ||||||
|  * @author Bill Kuker <bkuker@billkuker.com> |  * @author Bill Kuker <bkuker@billkuker.com> | ||||||
|  * @author Daniel Williams <equipoise@gmail.com> |  * @author Daniel Williams <equipoise@gmail.com> | ||||||
| @ -314,19 +316,32 @@ public class ComponentRenderer { | |||||||
| 			glu.gluCylinder(q, ir, ir, r.getInnerHeight(), LOD, 1); | 			glu.gluCylinder(q, ir, ir, r.getInnerHeight(), LOD, 1); | ||||||
| 			 | 			 | ||||||
| 			// Flange Cylinder | 			// Flange Cylinder | ||||||
| 			if (r.getFlangeHeight() > 0) { |  | ||||||
| 			gl.glTranslated(0, 0, r.getInnerHeight()); | 			gl.glTranslated(0, 0, r.getInnerHeight()); | ||||||
|  | 			if (r.getFlangeHeight() > 0) { | ||||||
| 				glu.gluCylinder(q, or, or, r.getFlangeHeight(), LOD, 1); | 				glu.gluCylinder(q, or, or, r.getFlangeHeight(), LOD, 1); | ||||||
| 				glu.gluQuadricOrientation(q, GLU.GLU_INSIDE); | 				glu.gluQuadricOrientation(q, GLU.GLU_INSIDE); | ||||||
| 				glu.gluDisk(q, 0, or, LOD, 2); | 				glu.gluDisk(q, 0, or, LOD, 2); | ||||||
| 				glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE); | 				glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE); | ||||||
| 				gl.glTranslated(0, 0, r.getFlangeHeight()); | 				gl.glTranslated(0, 0, r.getFlangeHeight()); | ||||||
| 				glu.gluDisk(q, 0, or, LOD, 2); | 				glu.gluDisk(q, 0, or, LOD, 2); | ||||||
| 			} else {	// Draw a closing cap if there is no flange | 			} else if (r.getScrewHeight() == 0) {	// Draw a closing cap if there is no flange | ||||||
| 				gl.glTranslated(0, 0, r.getInnerHeight()); |  | ||||||
| 				glu.gluDisk(q, 0, ir, LOD, 2); | 				glu.gluDisk(q, 0, ir, LOD, 2); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			// Screw | ||||||
|  | 			if (r.getScrewHeight() > 0) { | ||||||
|  | 				// Half dome | ||||||
|  | 				gl.glClipPlane(GL2.GL_CLIP_PLANE0, new double[] { 0, 0, 1, 0 }, 0); | ||||||
|  | 				gl.glEnable(GL2.GL_CLIP_PLANE0); | ||||||
|  | 				gl.glScaled(1, 1, r.getScrewHeight() / (r.getOuterDiameter() / 2)); | ||||||
|  | 				glu.gluSphere(q, r.getOuterDiameter() / 2.0, LOD, LOD); | ||||||
|  | 				gl.glDisable(GL2.GL_CLIP_PLANE0); | ||||||
|  | 
 | ||||||
|  | 				// Closing disk | ||||||
|  | 				glu.gluQuadricOrientation(q, GLU.GLU_INSIDE); | ||||||
|  | 				glu.gluDisk(q, ir, or, LOD, 2); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| package net.sf.openrocket.gui.rocketfigure; | package net.sf.openrocket.gui.rocketfigure; | ||||||
| 
 | 
 | ||||||
| import java.awt.Shape; | import java.awt.Shape; | ||||||
|  | import java.awt.geom.AffineTransform; | ||||||
|  | import java.awt.geom.Arc2D; | ||||||
| import java.awt.geom.Ellipse2D; | import java.awt.geom.Ellipse2D; | ||||||
| import java.awt.geom.Line2D; | import java.awt.geom.Line2D; | ||||||
| import java.awt.geom.Path2D; | import java.awt.geom.Path2D; | ||||||
| @ -32,6 +34,7 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 		final double baseHeight = btn.getBaseHeight(); | 		final double baseHeight = btn.getBaseHeight(); | ||||||
| 		final double innerHeight = btn.getInnerHeight(); | 		final double innerHeight = btn.getInnerHeight(); | ||||||
| 		final double flangeHeight = btn.getFlangeHeight(); | 		final double flangeHeight = btn.getFlangeHeight(); | ||||||
|  | 		final double screwHeight = btn.getScrewHeight(); | ||||||
| 		 | 		 | ||||||
| 		final double outerDiameter = btn.getOuterDiameter(); | 		final double outerDiameter = btn.getOuterDiameter(); | ||||||
| 		final double outerRadius = outerDiameter/2; | 		final double outerRadius = outerDiameter/2; | ||||||
| @ -50,9 +53,16 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 		final double baseHeightcos = baseHeight*cosr; | 		final double baseHeightcos = baseHeight*cosr; | ||||||
| 		final double innerHeightcos = innerHeight*cosr; | 		final double innerHeightcos = innerHeight*cosr; | ||||||
| 		final double flangeHeightcos = flangeHeight*cosr; | 		final double flangeHeightcos = flangeHeight*cosr; | ||||||
|  | 		double screwHeightcos = screwHeight*cosr; | ||||||
|  | 
 | ||||||
|  | 		// Don't draw the screw if it will overlap with the ellipse of the flange | ||||||
|  | 		if (Math.abs(screwHeightcos) <= outerDiameter * Math.abs(sinr) / 2) { | ||||||
|  | 			screwHeightcos = 0; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		Path2D.Double path = new Path2D.Double(); | 		Path2D.Double path = new Path2D.Double(); | ||||||
| 		Path2D.Double pathInvis = new Path2D.Double();	// Path for the invisible triangles | 		Path2D.Double pathInvis = new Path2D.Double();	// Invisible paths to be used for selection of the rail button | ||||||
|  | 		Arc2D.Double screwShape = null; | ||||||
| 		{// base cylinder | 		{// base cylinder | ||||||
| 			if (baseHeight > 0) { | 			if (baseHeight > 0) { | ||||||
| 				final double drawWidth = outerDiameter; | 				final double drawWidth = outerDiameter; | ||||||
| @ -99,7 +109,7 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 			pathInvis.append(new Rectangle2D.Double(center.x - innerRadius, y_invis, drawWidth, Math.abs(innerHeightcos)), false); | 			pathInvis.append(new Rectangle2D.Double(center.x - innerRadius, y_invis, drawWidth, Math.abs(innerHeightcos)), false); | ||||||
| 		} | 		} | ||||||
| 		{// flange cylinder | 		{// flange cylinder | ||||||
| 			if (flangeHeight > 0) { | 			if (flangeHeight > 0 || screwHeight > 0) {		// Also draw when there is a screw (= the bottom of the screw) | ||||||
| 				final double drawWidth = outerDiameter; | 				final double drawWidth = outerDiameter; | ||||||
| 				final double drawHeight = outerDiameter * sinr; | 				final double drawHeight = outerDiameter * sinr; | ||||||
| 				final Point2D.Double center = new Point2D.Double(loc.x, loc.y + baseHeightcos + innerHeightcos); | 				final Point2D.Double center = new Point2D.Double(loc.x, loc.y + baseHeightcos + innerHeightcos); | ||||||
| @ -121,12 +131,22 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 				pathInvis.append(new Rectangle2D.Double(center.x - outerRadius, y_invis, drawWidth, Math.abs(flangeHeightcos)), false); | 				pathInvis.append(new Rectangle2D.Double(center.x - outerRadius, y_invis, drawWidth, Math.abs(flangeHeightcos)), false); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		{// screw | ||||||
|  | 			if (screwHeight > 0) { | ||||||
|  | 				final double drawWidth = outerDiameter; | ||||||
|  | 				final double drawHeight = Math.abs(screwHeightcos) * 2;        // Times 2 because it is the full ellipse height | ||||||
|  | 				final Point2D.Double origin = new Point2D.Double(loc.x - outerRadius, loc.y + baseHeightcos + innerHeightcos + flangeHeightcos - Math.abs(screwHeightcos)); | ||||||
|  | 				screwShape = new Arc2D.Double(origin.x, origin.y, drawWidth, drawHeight, 0, -Math.signum(screwHeightcos) * 180, Arc2D.OPEN); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		RocketComponentShape[] shapes = RocketComponentShape.toArray(new Shape[]{ path }, component); | 		Shape[] temp = screwShape == null ? new Shape[]{ path } : new Shape[]{ path, screwShape }; | ||||||
|  | 		RocketComponentShape[] shapes = RocketComponentShape.toArray(temp, component); | ||||||
| 		RocketComponentShape[] shapesInvis = RocketComponentShape.toArray(new Shape[]{ pathInvis }, component); | 		RocketComponentShape[] shapesInvis = RocketComponentShape.toArray(new Shape[]{ pathInvis }, component); | ||||||
| 
 | 
 | ||||||
| 		for (RocketComponentShape s : shapesInvis) | 		for (RocketComponentShape s : shapesInvis) { | ||||||
| 			s.setColor(Color.INVISIBLE); | 			s.setColor(Color.INVISIBLE); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		RocketComponentShape[] total = Arrays.copyOf(shapes, shapes.length + shapesInvis.length); | 		RocketComponentShape[] total = Arrays.copyOf(shapes, shapes.length + shapesInvis.length); | ||||||
| 		System.arraycopy(shapesInvis, 0, total, shapes.length, shapesInvis.length); | 		System.arraycopy(shapesInvis, 0, total, shapes.length, shapesInvis.length); | ||||||
| @ -140,6 +160,7 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 		final double baseHeight = btn.getBaseHeight(); | 		final double baseHeight = btn.getBaseHeight(); | ||||||
| 		final double innerHeight = btn.getInnerHeight(); | 		final double innerHeight = btn.getInnerHeight(); | ||||||
| 		final double flangeHeight = btn.getFlangeHeight(); | 		final double flangeHeight = btn.getFlangeHeight(); | ||||||
|  | 		final double screwHeight = btn.getScrewHeight(); | ||||||
| 
 | 
 | ||||||
| 		final double outerDiameter = btn.getOuterDiameter(); | 		final double outerDiameter = btn.getOuterDiameter(); | ||||||
| 		final double outerRadius = outerDiameter/2; | 		final double outerRadius = outerDiameter/2; | ||||||
| @ -158,6 +179,7 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 		final double cosr = Math.cos(combined_angle_rad); | 		final double cosr = Math.cos(combined_angle_rad); | ||||||
| 		 | 		 | ||||||
| 		Path2D.Double path = new Path2D.Double(); | 		Path2D.Double path = new Path2D.Double(); | ||||||
|  | 		Shape screwShape = null; | ||||||
| 
 | 
 | ||||||
| 		// base | 		// base | ||||||
| 		if (baseHeight > 0) { | 		if (baseHeight > 0) { | ||||||
| @ -171,15 +193,27 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 			path.append( getRotatedRectangle( loc.z+delta_z, loc.y+delta_y, innerRadius, innerHeight, combined_angle_rad), false); | 			path.append( getRotatedRectangle( loc.z+delta_z, loc.y+delta_y, innerRadius, innerHeight, combined_angle_rad), false); | ||||||
| 		} | 		} | ||||||
| 		{// flange | 		{// flange | ||||||
| 			if (flangeHeight > 0) { | 			if (flangeHeight > 0 || screwHeight > 0) {		// Also draw when there is a screw (= the bottom of the screw) | ||||||
| 				final double delta_r = baseHeight + innerHeight; | 				final double delta_r = baseHeight + innerHeight; | ||||||
| 				final double delta_y = delta_r * cosr; | 				final double delta_y = delta_r * cosr; | ||||||
| 				final double delta_z = delta_r * sinr; | 				final double delta_z = delta_r * sinr; | ||||||
| 				path.append(getRotatedRectangle(loc.z + delta_z, loc.y + delta_y, outerRadius, flangeHeight, combined_angle_rad), false); | 				path.append(getRotatedRectangle(loc.z + delta_z, loc.y + delta_y, outerRadius, flangeHeight, combined_angle_rad), false); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		{// screw | ||||||
|  | 			if (screwHeight > 0) { | ||||||
|  | 				final double drawWidth = outerDiameter; | ||||||
|  | 				final double drawHeight = 2*screwHeight;	// Times 2 because it is the full ellipse height | ||||||
|  | 				final double delta_y = baseHeight + innerHeight + flangeHeight - screwHeight; | ||||||
|  | 				final double delta_z = -outerRadius; | ||||||
|  | 				final Point2D.Double origin = new Point2D.Double(loc.z + delta_z, loc.y + delta_y); | ||||||
|  | 				screwShape = new Arc2D.Double(origin.x, origin.y, drawWidth, drawHeight, 0, -180, Arc2D.OPEN); | ||||||
|  | 				screwShape = getRotatedShape(screwShape, loc.z, loc.y, -combined_angle_rad); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		return RocketComponentShape.toArray( new Shape[]{ path }, component); | 		Shape[] temp = screwShape == null ? new Shape[]{ path } : new Shape[]{ path, screwShape }; | ||||||
|  | 		return RocketComponentShape.toArray(temp, component); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	 | 	 | ||||||
| @ -197,4 +231,24 @@ public class RailButtonShapes extends RocketComponentShape { | |||||||
| 		 | 		 | ||||||
| 		return rect; | 		return rect; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Rotates a shape about the specified coordinates. | ||||||
|  | 	 * | ||||||
|  | 	 * @param base  the shape (<code>null</code> permitted, returns <code>null</code>). | ||||||
|  | 	 * @param angle  the angle (in radians). | ||||||
|  | 	 * @param x  the x coordinate for the rotation point (in Java2D space). | ||||||
|  | 	 * @param y  the y coordinate for the rotation point (in Java2D space). | ||||||
|  | 	 * | ||||||
|  | 	 * @return the rotated shape. | ||||||
|  | 	 * | ||||||
|  | 	 * @author David Gilbert | ||||||
|  | 	 */ | ||||||
|  | 	public static Shape getRotatedShape(final Shape base, final double x, final double y, final double angle) { | ||||||
|  | 		if (base == null) { | ||||||
|  | 			return null; | ||||||
|  | 		} | ||||||
|  | 		final AffineTransform rotate = AffineTransform.getRotateInstance(angle, x, y); | ||||||
|  | 		return rotate.createTransformedShape(base); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user