Merge pull request #513 from teyrana/refactor_instance_map
Refactor instance map
This commit is contained in:
commit
1abf0d3834
@ -4,6 +4,7 @@ import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@ -18,6 +19,7 @@ import net.sf.openrocket.util.BoundingBox;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Monitorable;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
|
||||
/**
|
||||
@ -36,9 +38,9 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
protected final Rocket rocket;
|
||||
protected final FlightConfigurationId fcid;
|
||||
|
||||
private static int instanceCount=0;
|
||||
private static int configurationInstanceCount=0;
|
||||
// made public for testing.... there is probably a better way
|
||||
public final int instanceNumber;
|
||||
public final int configurationInstanceId;
|
||||
|
||||
private class StageFlags implements Cloneable {
|
||||
public boolean active = true;
|
||||
@ -83,7 +85,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
this.rocket = rocket;
|
||||
this.configurationName = null;
|
||||
this.instanceNumber = instanceCount++;
|
||||
this.configurationInstanceId = configurationInstanceCount++;
|
||||
|
||||
updateStages();
|
||||
updateMotors();
|
||||
@ -172,9 +174,29 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
return stages.get(stageNumber).active;
|
||||
}
|
||||
|
||||
public Collection<RocketComponent> getAllComponents() {
|
||||
Queue<RocketComponent> toProcess = new ArrayDeque<RocketComponent>();
|
||||
toProcess.offer(this.rocket);
|
||||
|
||||
ArrayList<RocketComponent> toReturn = new ArrayList<>();
|
||||
|
||||
while (!toProcess.isEmpty()) {
|
||||
RocketComponent comp = toProcess.poll();
|
||||
|
||||
toReturn.add(comp);
|
||||
for (RocketComponent child : comp.getChildren()) {
|
||||
if (!(child instanceof AxialStage)) {
|
||||
toProcess.offer(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
// this method is deprecated because it ignores instancing of parent components (e.g. Strapons or pods )
|
||||
// if you're calling this method, you're probably not getting the numbers you expect.
|
||||
// depending on your context, this may or may not be what you want.
|
||||
// recomend migrating to either: `getAllComponents` or `getActiveInstances`
|
||||
@Deprecated
|
||||
public Collection<RocketComponent> getActiveComponents() {
|
||||
Queue<RocketComponent> toProcess = new ArrayDeque<RocketComponent>(this.getActiveStages());
|
||||
@ -193,6 +215,49 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates a read-only, instance-aware collection of the components for this rocket & configuration
|
||||
*
|
||||
* TODO: swap in this function for the 'getActiveComponents() function, above; ONLY WHEN READY / MATURE!
|
||||
*/
|
||||
public InstanceMap getActiveInstances() {
|
||||
InstanceMap contexts = new InstanceMap();
|
||||
getContextListAt( this.rocket, contexts, Transformation.IDENTITY);
|
||||
return contexts;
|
||||
}
|
||||
|
||||
private InstanceMap getContextListAt(final RocketComponent component, final InstanceMap results, final Transformation parentTransform ){
|
||||
final int instanceCount = component.getInstanceCount();
|
||||
final Coordinate[] allOffsets = component.getInstanceOffsets();
|
||||
final double[] allAngles = component.getInstanceAngles();
|
||||
final boolean active = this.isComponentActive(component);
|
||||
|
||||
final Transformation compLocTransform = Transformation.getTranslationTransform( component.getPosition() );
|
||||
final Transformation componentTransform = parentTransform.applyTransformation(compLocTransform);
|
||||
|
||||
// generate the Instance's Context:
|
||||
for(int currentInstanceNumber=0; currentInstanceNumber < instanceCount; currentInstanceNumber++) {
|
||||
|
||||
final Coordinate instanceOffset = allOffsets[currentInstanceNumber];
|
||||
final Transformation offsetTransform = Transformation.getTranslationTransform( instanceOffset );
|
||||
|
||||
final double instanceAngle = allAngles[currentInstanceNumber];
|
||||
final Transformation angleTransform = Transformation.getAxialRotation(instanceAngle);
|
||||
|
||||
final Transformation currentTransform = componentTransform.applyTransformation(offsetTransform)
|
||||
.applyTransformation(angleTransform);
|
||||
|
||||
// constructs entry in-place
|
||||
results.emplace(component, active, currentInstanceNumber, currentTransform);
|
||||
|
||||
for(RocketComponent child : component.getChildren()) {
|
||||
getContextListAt(child, results, currentTransform);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public List<AxialStage> getActiveStages() {
|
||||
List<AxialStage> activeStages = new ArrayList<>();
|
||||
@ -534,14 +599,14 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
|
||||
public String toDebug() {
|
||||
return this.fcid.toDebug()+" (#"+instanceNumber+") "+ getOneLineMotorDescription();
|
||||
return this.fcid.toDebug()+" (#"+configurationInstanceId+") "+ getOneLineMotorDescription();
|
||||
}
|
||||
|
||||
// DEBUG / DEVEL
|
||||
public String toStageListDetail() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(String.format("\nDumping %d stages for config: %s: (%s)(#: %d)\n",
|
||||
stages.size(), getName(), getId().toShortKey(), instanceNumber));
|
||||
stages.size(), getName(), getId().toShortKey(), configurationInstanceId));
|
||||
final String fmt = " [%-2s][%4s]: %6s \n";
|
||||
buf.append(String.format(fmt, "#", "?actv", "Name"));
|
||||
for (StageFlags flags : stages.values()) {
|
||||
@ -556,7 +621,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
public String toMotorDetail(){
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(String.format("\nDumping %2d Motors for configuration %s (%s)(#: %s)\n",
|
||||
motors.size(), getName(), getId().toShortKey(), this.instanceNumber));
|
||||
motors.size(), getName(), getId().toShortKey(), this.configurationInstanceId));
|
||||
|
||||
for( MotorConfiguration curConfig : this.motors.values() ){
|
||||
boolean active=this.isStageActive( curConfig.getMount().getStage().getStageNumber());
|
||||
|
@ -0,0 +1,59 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author teyrana (aka Daniel Williams) <equipoise@gmail.com>
|
||||
*
|
||||
*/
|
||||
public class InstanceContext {
|
||||
|
||||
// =========== Public Functions ========================
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
InstanceContext other = (InstanceContext) obj;
|
||||
return (component.equals(other.component) && transform.equals(other.transform));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) (component.hashCode());
|
||||
}
|
||||
|
||||
public InstanceContext(final RocketComponent _component, final boolean _active, final int _instanceNumber, final Transformation _transform) {
|
||||
component = _component;
|
||||
active = _active;
|
||||
instanceNumber = _instanceNumber;
|
||||
transform = _transform;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Context for %s #%d", component);
|
||||
}
|
||||
|
||||
public Coordinate getLocation() {
|
||||
return transform.transform(Coordinate.ZERO);
|
||||
}
|
||||
|
||||
// =========== Instance Member Variables ========================
|
||||
|
||||
|
||||
// ==== public ====
|
||||
final public RocketComponent component;
|
||||
final public boolean active;
|
||||
final public int instanceNumber;
|
||||
final public Transformation transform;
|
||||
|
||||
// =========== Private Instance Functions ========================
|
||||
|
||||
|
||||
}
|
||||
|
73
core/src/net/sf/openrocket/rocketcomponent/InstanceMap.java
Normal file
73
core/src/net/sf/openrocket/rocketcomponent/InstanceMap.java
Normal file
@ -0,0 +1,73 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author teyrana (aka Daniel Williams) <equipoise@gmail.com>
|
||||
*
|
||||
*/
|
||||
public class InstanceMap extends HashMap<RocketComponent, ArrayList<InstanceContext>> {
|
||||
|
||||
// =========== Public Functions ========================
|
||||
|
||||
// public InstanceMap() {}
|
||||
|
||||
public int count(final RocketComponent key) {
|
||||
if(containsKey(key)){
|
||||
return get(key).size();
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void emplace(final RocketComponent component, boolean active, int number, final Transformation xform) {
|
||||
final RocketComponent key = component;
|
||||
|
||||
if(!containsKey(component)) {
|
||||
put(key, new ArrayList<>());
|
||||
}
|
||||
|
||||
final InstanceContext context = new InstanceContext(component, active, number, xform);
|
||||
get(key).add(context);
|
||||
}
|
||||
|
||||
public List<InstanceContext> getInstanceContexts(final RocketComponent key) {
|
||||
return get(key);
|
||||
}
|
||||
|
||||
// this is primarily for debugging.
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
int outerIndex = 0;
|
||||
buffer.append(">> Printing InstanceMap:\n");
|
||||
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: entrySet() ) {
|
||||
final RocketComponent key = entry.getKey();
|
||||
final ArrayList<InstanceContext> contexts = entry.getValue();
|
||||
buffer.append(String.format("....[% 2d]:[%s]\n", outerIndex, key.getName()));
|
||||
outerIndex++;
|
||||
|
||||
int innerIndex = 0;
|
||||
for(InstanceContext ctxt: contexts ) {
|
||||
buffer.append(String.format("........[@% 2d][% 2d] %s\n", innerIndex, ctxt.instanceNumber, ctxt.getLocation().toPreciseString()));
|
||||
innerIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
// =========== Instance Member Variables ========================
|
||||
|
||||
// =========== Private Instance Functions ========================
|
||||
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ import net.sf.openrocket.rocketcomponent.FinSet.CrossSection;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.IllegalFinPointException;
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
import net.sf.openrocket.rocketcomponent.InternalComponent;
|
||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||
@ -862,7 +861,7 @@ public class TestRockets {
|
||||
// ====== Payload Stage ======
|
||||
// ====== ====== ====== ======
|
||||
AxialStage payloadStage = new AxialStage();
|
||||
payloadStage.setName("Payload Fairing");
|
||||
payloadStage.setName("Payload Fairing Stage");
|
||||
rocket.addChild(payloadStage);
|
||||
|
||||
{
|
||||
|
@ -5,14 +5,16 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.TestRockets;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
|
||||
public class FlightConfigurationTest extends BaseTestCase {
|
||||
|
||||
private final static double EPSILON = MathUtil.EPSILON*1E3;
|
||||
|
||||
/**
|
||||
@ -155,7 +157,6 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
|
||||
// test explicitly setting all stages active
|
||||
config.setAllStages();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -326,5 +327,151 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
assertThat("active motor count doesn't match: ", actualMotorCount, equalTo(expectedMotorCount));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterateComponents() {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
FlightConfiguration selected = rocket.getSelectedConfiguration();
|
||||
|
||||
selected.clearAllStages();
|
||||
selected.toggleStage(2);
|
||||
|
||||
// vvvv Test Target vvvv
|
||||
InstanceMap instances = selected.getActiveInstances();
|
||||
// ^^^^ Test Target ^^^^
|
||||
|
||||
// Payload Stage
|
||||
final AxialStage coreStage = (AxialStage)rocket.getChild(1);
|
||||
{ // Core Stage
|
||||
final List<InstanceContext> coreStageContextList = instances.getInstanceContexts(coreStage);
|
||||
final InstanceContext coreStageContext = coreStageContextList.get(0);
|
||||
assertThat(coreStageContext.component.getClass(), equalTo(AxialStage.class));
|
||||
assertThat(coreStageContext.component.getID(), equalTo(rocket.getChild(1).getID()));
|
||||
assertThat(coreStageContext.component.getInstanceCount(), equalTo(1));
|
||||
|
||||
final Coordinate coreLocation = coreStageContext.getLocation();
|
||||
assertEquals(coreLocation.x, 0.564, EPSILON);
|
||||
assertEquals(coreLocation.y, 0.0, EPSILON);
|
||||
assertEquals(coreLocation.z, 0.0, EPSILON);
|
||||
|
||||
//... skip uninteresting component
|
||||
}
|
||||
|
||||
// Booster Stage
|
||||
{ // instance #1
|
||||
final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(0);
|
||||
final List<InstanceContext> boosterStageContextList = instances.getInstanceContexts(boosterStage);
|
||||
final InstanceContext boosterStage0Context = boosterStageContextList.get(0);
|
||||
assertThat(boosterStage0Context.component.getClass(), equalTo(ParallelStage.class));
|
||||
assertThat(boosterStage0Context.component.getID(), equalTo(boosterStage.getID()));
|
||||
assertThat(boosterStage0Context.instanceNumber, equalTo(0));
|
||||
{
|
||||
final Coordinate loc = boosterStage0Context.getLocation();
|
||||
assertEquals(loc.x, 0.484, EPSILON);
|
||||
assertEquals(loc.y, 0.077, EPSILON);
|
||||
assertEquals(loc.z, 0.0, EPSILON);
|
||||
}
|
||||
|
||||
final InstanceContext boosterStage1Context = boosterStageContextList.get(1);
|
||||
assertThat(boosterStage1Context.component.getClass(), equalTo(ParallelStage.class));
|
||||
assertThat(boosterStage1Context.component.getID(), equalTo(boosterStage.getID()));
|
||||
assertThat(boosterStage1Context.instanceNumber, equalTo(1));
|
||||
{
|
||||
final Coordinate loc = boosterStage1Context.getLocation();
|
||||
assertEquals(loc.x, 0.484, EPSILON);
|
||||
assertEquals(loc.y, -0.077, EPSILON);
|
||||
assertEquals(loc.z, 0.0, EPSILON);
|
||||
}
|
||||
|
||||
{ // Booster Body:
|
||||
final BodyTube boosterBody = (BodyTube)boosterStage.getChild(1);
|
||||
final List<InstanceContext> boosterBodyContextList = instances.getInstanceContexts(boosterBody);
|
||||
|
||||
// this is the instance number rocket-wide
|
||||
final InstanceContext boosterBodyContext = boosterBodyContextList.get(1);
|
||||
|
||||
// this is the instance number per-parent
|
||||
assertThat(boosterBodyContext.instanceNumber, equalTo(0));
|
||||
|
||||
assertThat(boosterBodyContext.component.getClass(), equalTo(BodyTube.class));
|
||||
|
||||
final Coordinate bodyTubeLocation = boosterBodyContext.getLocation();
|
||||
assertEquals(bodyTubeLocation.x, 0.564, EPSILON);
|
||||
assertEquals(bodyTubeLocation.y, -0.077, EPSILON);
|
||||
assertEquals(bodyTubeLocation.z, 0.0, EPSILON);
|
||||
|
||||
{ // Booster::Motor Tubes ( x2 x4)
|
||||
final InnerTube boosterMMT = (InnerTube)boosterBody.getChild(0);
|
||||
final List<InstanceContext> mmtContextList = instances.getInstanceContexts(boosterMMT);
|
||||
assertEquals(8, mmtContextList.size());
|
||||
|
||||
final InstanceContext motorTubeContext0 = mmtContextList.get(4);
|
||||
assertThat(motorTubeContext0.component.getClass(), equalTo(InnerTube.class));
|
||||
assertThat(motorTubeContext0.instanceNumber, equalTo(0));
|
||||
final Coordinate motorTube0Location = motorTubeContext0.getLocation();
|
||||
assertEquals(motorTube0Location.x, 1.214, EPSILON);
|
||||
assertEquals(motorTube0Location.y, -0.062, EPSILON);
|
||||
assertEquals(motorTube0Location.z, -0.015, EPSILON);
|
||||
|
||||
final InstanceContext motorTubeContext1 = mmtContextList.get(5);
|
||||
assertThat(motorTubeContext1.component.getClass(), equalTo(InnerTube.class));
|
||||
assertThat(motorTubeContext1.instanceNumber, equalTo(1));
|
||||
final Coordinate motorTube1Location = motorTubeContext1.getLocation();
|
||||
assertEquals(motorTube1Location.x, 1.214, EPSILON);
|
||||
assertEquals(motorTube1Location.y, -0.092, EPSILON);
|
||||
assertEquals(motorTube1Location.z, -0.015, EPSILON);
|
||||
|
||||
final InstanceContext motorTubeContext2 = mmtContextList.get(6);
|
||||
assertThat(motorTubeContext2.component.getClass(), equalTo(InnerTube.class));
|
||||
assertThat(motorTubeContext2.instanceNumber, equalTo(2));
|
||||
final Coordinate motorTube2Location = motorTubeContext2.getLocation();
|
||||
assertEquals(motorTube2Location.x, 1.214, EPSILON);
|
||||
assertEquals(motorTube2Location.y, -0.092, EPSILON);
|
||||
assertEquals(motorTube2Location.z, 0.015, EPSILON);
|
||||
|
||||
final InstanceContext motorTubeContext3 = mmtContextList.get(7);
|
||||
assertThat(motorTubeContext3.component.getClass(), equalTo(InnerTube.class));
|
||||
assertThat(motorTubeContext3.instanceNumber, equalTo(3));
|
||||
final Coordinate motorTube3Location = motorTubeContext3.getLocation();
|
||||
assertEquals(motorTube3Location.x, 1.214, EPSILON);
|
||||
assertEquals(motorTube3Location.y, -0.062, EPSILON);
|
||||
assertEquals(motorTube3Location.z, 0.015, EPSILON);
|
||||
|
||||
}{ // Booster::Fins::Instances ( x2 x3)
|
||||
final FinSet fins = (FinSet)boosterBody.getChild(1);
|
||||
final List<InstanceContext> finContextList = instances.getInstanceContexts(fins);
|
||||
assertEquals(6, finContextList.size());
|
||||
|
||||
final InstanceContext boosterFinContext0 = finContextList.get(3);
|
||||
assertThat(boosterFinContext0.component.getClass(), equalTo(TrapezoidFinSet.class));
|
||||
assertThat(boosterFinContext0.instanceNumber, equalTo(0));
|
||||
final Coordinate boosterFin0Location = boosterFinContext0.getLocation();
|
||||
assertEquals(boosterFin0Location.x, 1.044, EPSILON);
|
||||
assertEquals(boosterFin0Location.y, -0.104223611, EPSILON);
|
||||
assertEquals(boosterFin0Location.z, -0.027223611, EPSILON);
|
||||
|
||||
final InstanceContext boosterFinContext1 = finContextList.get(4);
|
||||
assertThat(boosterFinContext1.component.getClass(), equalTo(TrapezoidFinSet.class));
|
||||
assertThat(boosterFinContext1.instanceNumber, equalTo(1));
|
||||
final Coordinate boosterFin1Location = boosterFinContext1.getLocation();
|
||||
assertEquals(boosterFin1Location.x, 1.044, EPSILON);
|
||||
assertEquals(boosterFin1Location.y, -0.03981186, EPSILON);
|
||||
assertEquals(boosterFin1Location.z, -0.00996453, EPSILON);
|
||||
|
||||
final InstanceContext boosterFinContext2 = finContextList.get(5);
|
||||
assertThat(boosterFinContext2.component.getClass(), equalTo(TrapezoidFinSet.class));
|
||||
assertThat(boosterFinContext2.instanceNumber, equalTo(2));
|
||||
final Coordinate boosterFin2Location = boosterFinContext2.getLocation();
|
||||
assertEquals(boosterFin2Location.x, 1.044, EPSILON);
|
||||
assertEquals(boosterFin2Location.y, -0.08696453, EPSILON);
|
||||
assertEquals(boosterFin2Location.z, 0.03718814, EPSILON);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,7 +7,6 @@ import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.rocketcomponent.position.AngleMethod;
|
||||
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
@ -35,12 +34,12 @@ public class RocketTest extends BaseTestCase {
|
||||
FlightConfigurationId fcid4 = config4.getId();
|
||||
|
||||
assertThat("fcids should match: ", config1.getId().key, equalTo(fcid4.key));
|
||||
assertThat("Configurations should be different: "+config1.toDebug()+"=?="+config4.toDebug(), config1.instanceNumber, not( config4.instanceNumber));
|
||||
assertThat("Configurations should be different: "+config1.toDebug()+"=?="+config4.toDebug(), config1.configurationInstanceId, not( config4.configurationInstanceId));
|
||||
|
||||
FlightConfiguration config5 = rkt2.getFlightConfiguration(config2.getId());
|
||||
FlightConfigurationId fcid5 = config5.getId();
|
||||
assertThat("fcids should match: ", config2.getId(), equalTo(fcid5));
|
||||
assertThat("Configurations should bef different match: "+config2.toDebug()+"=?="+config5.toDebug(), config2.instanceNumber, not( config5.instanceNumber));
|
||||
assertThat("Configurations should bef different match: "+config2.toDebug()+"=?="+config5.toDebug(), config2.configurationInstanceId, not( config5.configurationInstanceId));
|
||||
}
|
||||
|
||||
|
||||
@ -260,7 +259,7 @@ public class RocketTest extends BaseTestCase {
|
||||
loc = coreBody.getComponentLocations()[0];
|
||||
assertEquals(coreBody.getName()+" offset is incorrect: ", 0.0, offset.x, EPSILON);
|
||||
assertEquals(coreBody.getName()+" location is incorrect: ", 0.564, loc.x, EPSILON);
|
||||
|
||||
|
||||
// ====== Booster Set Stage ======
|
||||
// ====== ====== ======
|
||||
ParallelStage boosters = (ParallelStage) coreBody.getChild(0);
|
||||
|
@ -4,6 +4,7 @@ import java.awt.Point;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
@ -23,6 +24,8 @@ import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||
import net.sf.openrocket.rocketcomponent.InstanceMap;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
@ -159,39 +162,29 @@ public abstract class RocketRenderer {
|
||||
|
||||
private Collection<Geometry> getTreeGeometry( FlightConfiguration config){
|
||||
System.err.println(String.format("==== Building tree geometry ===="));
|
||||
return getTreeGeometry("", new ArrayList<Geometry>(), config, config.getRocket(), Transformation.IDENTITY);
|
||||
}
|
||||
|
||||
private Collection<Geometry> getTreeGeometry(String indent, Collection<Geometry> treeGeometry, FlightConfiguration config, RocketComponent comp, final Transformation parentTransform){
|
||||
final int instanceCount = comp.getInstanceCount();
|
||||
double[] instanceAngles = comp.getInstanceAngles();
|
||||
Coordinate[] instanceLocations = comp.getInstanceLocations();
|
||||
|
||||
if( instanceLocations.length != instanceAngles.length ){
|
||||
throw new ArrayIndexOutOfBoundsException(String.format("lengths of location array (%d) and angle arrays (%d) differs! (in: %s) ", instanceLocations.length, instanceAngles.length, comp.getName()));
|
||||
}
|
||||
// input
|
||||
final InstanceMap imap = config.getActiveInstances();
|
||||
|
||||
// output buffer
|
||||
final Collection<Geometry> treeGeometry = new ArrayList<Geometry>();
|
||||
|
||||
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
|
||||
final RocketComponent comp = entry.getKey();
|
||||
|
||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||
System.err.println(String.format("....[%s]", comp.getName()));
|
||||
|
||||
// iterate over the aggregated instances for the whole tree.
|
||||
for( int instanceNumber = 0; instanceNumber < instanceCount; ++instanceNumber) {
|
||||
Coordinate currentLocation = instanceLocations[instanceNumber];
|
||||
final double currentAngle = instanceAngles[instanceNumber];
|
||||
|
||||
// System.err.println( String.format("%s[ %s ]", indent, comp.getName()));
|
||||
// System.err.println( String.format("%s :: %12.8g / %12.8g / %12.8g (m) @ %8.4g (rads) ", indent, currentLocation.x, currentLocation.y, currentLocation.z, currentAngle ));
|
||||
|
||||
Transformation currentTransform = parentTransform
|
||||
.applyTransformation( Transformation.getTranslationTransform( currentLocation))
|
||||
.applyTransformation( Transformation.rotate_x( currentAngle ));
|
||||
for(InstanceContext context: contextList ) {
|
||||
System.err.println(String.format("........[% 2d] %s", context.instanceNumber, context.getLocation().toPreciseString()));
|
||||
|
||||
|
||||
// recurse into inactive trees: allow active stages inside inactive stages
|
||||
for(RocketComponent child: comp.getChildren()) {
|
||||
getTreeGeometry(indent+" ", treeGeometry, config, child, currentTransform );
|
||||
}
|
||||
// System.err.println( String.format("%s[ %s ]", indent, comp.getName()));
|
||||
// System.err.println( String.format("%s :: %12.8g / %12.8g / %12.8g (m) @ %8.4g (rads) ", indent, currentLocation.x, currentLocation.y, currentLocation.z, currentAngle ));
|
||||
|
||||
Geometry geom = cr.getComponentGeometry( comp, currentTransform );
|
||||
geom.active = config.isComponentActive( comp );
|
||||
treeGeometry.add( geom );
|
||||
Geometry instanceGeometry = cr.getComponentGeometry( comp, context.transform );
|
||||
instanceGeometry.active = context.active;
|
||||
treeGeometry.add( instanceGeometry );
|
||||
}
|
||||
}
|
||||
return treeGeometry;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class PrintableNoseCone extends AbstractPrintable<NoseCone> {
|
||||
*/
|
||||
@Override
|
||||
protected void draw(Graphics2D g2) {
|
||||
RocketComponentShape[] compShapes = TransitionShapes.getShapesSide(target, Transformation.rotate_x(0d), new Coordinate(0,0,0), PrintUnit.METERS.toPoints(1));
|
||||
RocketComponentShape[] compShapes = TransitionShapes.getShapesSide(target, Transformation.IDENTITY, PrintUnit.METERS.toPoints(1));
|
||||
|
||||
if (compShapes != null && compShapes.length > 0) {
|
||||
Rectangle r = compShapes[0].shape.getBounds();
|
||||
|
@ -4,15 +4,12 @@ import java.awt.Shape;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
public class BodyTubeShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation){
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
|
||||
BodyTube tube = (BodyTube)component;
|
||||
|
||||
@ -20,22 +17,19 @@ public class BodyTubeShapes extends RocketComponentShape {
|
||||
double radius = tube.getOuterRadius();
|
||||
|
||||
Shape[] s = new Shape[1];
|
||||
s[0] = TubeShapes.getShapesSide( transformation, componentAbsoluteLocation, length, radius );
|
||||
s[0] = TubeShapes.getShapesSide( transformation, length, radius );
|
||||
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
BodyTube tube = (BodyTube)component;
|
||||
|
||||
double radius = tube.getOuterRadius();
|
||||
|
||||
Shape[] s = new Shape[1];
|
||||
s[0] = TubeShapes.getShapesBack( transformation, componentAbsoluteLocation, radius);
|
||||
s[0] = TubeShapes.getShapesBack( transformation, radius);
|
||||
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import java.util.ArrayList;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
@ -15,11 +14,10 @@ import net.sf.openrocket.util.Transformation;
|
||||
public class FinSetShapes extends RocketComponentShape {
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation ){
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component,
|
||||
final Transformation transformation){
|
||||
final FinSet finset = (FinSet) component;
|
||||
|
||||
|
||||
// this supplied transformation includes:
|
||||
// - baseRotationTransformation
|
||||
// - mount-radius transformtion
|
||||
@ -47,40 +45,37 @@ public class FinSetShapes extends RocketComponentShape {
|
||||
ArrayList<RocketComponentShape> shapeList = new ArrayList<>();
|
||||
|
||||
// Make fin polygon
|
||||
shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, finPoints), finset));
|
||||
shapeList.add(new RocketComponentShape(generatePath(finPoints), finset));
|
||||
|
||||
// Make fin polygon
|
||||
shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, tabPoints), finset));
|
||||
shapeList.add(new RocketComponentShape(generatePath(tabPoints), finset));
|
||||
|
||||
// Make fin polygon
|
||||
shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, rootPoints), finset));
|
||||
shapeList.add(new RocketComponentShape(generatePath(rootPoints), finset));
|
||||
|
||||
return shapeList.toArray(new RocketComponentShape[0]);
|
||||
}
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate location) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
FinSet finset = (FinSet) component;
|
||||
|
||||
|
||||
Shape[] toReturn;
|
||||
|
||||
if (MathUtil.equals(finset.getCantAngle(), 0)) {
|
||||
toReturn = uncantedShapesBack(finset, transformation, location);
|
||||
toReturn = uncantedShapesBack(finset, transformation);
|
||||
} else {
|
||||
toReturn = cantedShapesBack(finset, transformation, location);
|
||||
toReturn = cantedShapesBack(finset, transformation);
|
||||
}
|
||||
|
||||
|
||||
return RocketComponentShape.toArray(toReturn, finset);
|
||||
}
|
||||
|
||||
private static Path2D.Float generatePath(final Coordinate c0, final Coordinate[] points){
|
||||
private static Path2D.Float generatePath(final Coordinate[] points){
|
||||
Path2D.Float finShape = new Path2D.Float();
|
||||
for( int i = 0; i < points.length; i++){
|
||||
Coordinate curPoint = c0.add(points[i]);
|
||||
Coordinate curPoint = points[i];
|
||||
if (i == 0)
|
||||
finShape.moveTo(curPoint.x, curPoint.y);
|
||||
else
|
||||
@ -90,8 +85,7 @@ public class FinSetShapes extends RocketComponentShape {
|
||||
}
|
||||
|
||||
private static Shape[] uncantedShapesBack(FinSet finset,
|
||||
Transformation transformation,
|
||||
Coordinate finFront) {
|
||||
Transformation transformation) {
|
||||
|
||||
double thickness = finset.getThickness();
|
||||
double height = finset.getSpan();
|
||||
@ -110,13 +104,13 @@ public class FinSetShapes extends RocketComponentShape {
|
||||
Coordinate a;
|
||||
Path2D.Double p = new Path2D.Double();
|
||||
|
||||
a = finFront.add( c[0] );
|
||||
a = c[0];
|
||||
p.moveTo(a.z, a.y);
|
||||
a = finFront.add( c[1] );
|
||||
a = c[1];
|
||||
p.lineTo(a.z, a.y);
|
||||
a = finFront.add( c[2] );
|
||||
a = c[2];
|
||||
p.lineTo(a.z, a.y);
|
||||
a = finFront.add( c[3] );
|
||||
a = c[3];
|
||||
p.lineTo(a.z, a.y);
|
||||
p.closePath();
|
||||
|
||||
@ -126,8 +120,7 @@ public class FinSetShapes extends RocketComponentShape {
|
||||
|
||||
// TODO: LOW: Jagged shapes from back draw incorrectly.
|
||||
private static Shape[] cantedShapesBack(FinSet finset,
|
||||
Transformation transformation,
|
||||
Coordinate location) {
|
||||
Transformation transformation) {
|
||||
int i;
|
||||
int fins = finset.getFinCount();
|
||||
double thickness = finset.getThickness();
|
||||
@ -179,15 +172,15 @@ public class FinSetShapes extends RocketComponentShape {
|
||||
s = new Shape[fins*2];
|
||||
for (int fin=0; fin<fins; fin++) {
|
||||
|
||||
s[2*fin] = makePolygonBack(sidePoints,finset,transformation, location);
|
||||
s[2*fin+1] = makePolygonBack(backPoints,finset,transformation, location);
|
||||
s[2*fin] = makePolygonBack(sidePoints,finset,transformation);
|
||||
s[2*fin+1] = makePolygonBack(backPoints,finset,transformation);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
s = new Shape[fins];
|
||||
for (int fin=0; fin<fins; fin++) {
|
||||
s[fin] = makePolygonBack(sidePoints,finset,transformation, location);
|
||||
s[fin] = makePolygonBack(sidePoints,finset,transformation);
|
||||
}
|
||||
|
||||
}
|
||||
@ -195,11 +188,11 @@ public class FinSetShapes extends RocketComponentShape {
|
||||
return s;
|
||||
}
|
||||
|
||||
private static Shape makePolygonBack(Coordinate[] array, FinSet finset,
|
||||
Transformation t, Coordinate location) {
|
||||
private static Shape makePolygonBack(Coordinate[] array, FinSet finset, final Transformation t) {
|
||||
Path2D.Float p;
|
||||
|
||||
Coordinate compCenter = location;
|
||||
Coordinate compCenter = t.transform(Coordinate.ZERO);
|
||||
|
||||
// Make polygon
|
||||
p = new Path2D.Float();
|
||||
for (int i=0; i < array.length; i++) {
|
||||
|
@ -10,32 +10,26 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
public class LaunchLugShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation) {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
LaunchLug lug = (LaunchLug)component;
|
||||
double length = lug.getLength();
|
||||
double radius = lug.getOuterRadius();
|
||||
|
||||
Shape[] s = new Shape[]{
|
||||
TubeShapes.getShapesSide( transformation, instanceAbsoluteLocation, length, radius )
|
||||
TubeShapes.getShapesSide( transformation, length, radius )
|
||||
};
|
||||
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
LaunchLug lug = (LaunchLug)component;
|
||||
double radius = lug.getOuterRadius();
|
||||
|
||||
Shape[] s = new Shape[]{TubeShapes.getShapesBack( transformation, instanceAbsoluteLocation, radius)};
|
||||
Shape[] s = new Shape[]{TubeShapes.getShapesBack( transformation, radius)};
|
||||
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.Random;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.MassObject;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
@ -15,22 +18,19 @@ import net.sf.openrocket.util.Transformation;
|
||||
|
||||
public class MassComponentShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassComponent.MassComponentType type = ((net.sf.openrocket.rocketcomponent.MassComponent)component).getMassComponentType();
|
||||
MassComponent.MassComponentType type = ((MassComponent)component).getMassComponentType();
|
||||
|
||||
double length = tube.getLength();
|
||||
double radius = tube.getRadius();
|
||||
double arc = Math.min(length, 2*radius) * 0.7;
|
||||
|
||||
Coordinate start = transformation.transform( componentAbsoluteLocation);
|
||||
Shape[] s = new Shape[1];
|
||||
s[0] = new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc);
|
||||
final Coordinate start = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
Shape[] s = {new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc)};
|
||||
|
||||
switch (type) {
|
||||
case ALTIMETER:
|
||||
@ -61,21 +61,16 @@ public class MassComponentShapes extends RocketComponentShape {
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
double or = tube.getRadius();
|
||||
|
||||
Coordinate[] start = new Coordinate[]{transformation.transform( componentAbsoluteLocation )};
|
||||
|
||||
Shape[] s = new Shape[start.length];
|
||||
for (int i=0; i < start.length; i++) {
|
||||
s[i] = new Ellipse2D.Double((start[i].z-or),(start[i].y-or),2*or,2*or);
|
||||
}
|
||||
final Coordinate start = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
Shape[] s = {new Ellipse2D.Double((start.z-or),(start.y-or),2*or,2*or)};
|
||||
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
||||
|
@ -4,48 +4,40 @@ import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.MassObject;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
|
||||
public class MassObjectShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceOffset) {
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
MassObject tube = (MassObject)component;
|
||||
|
||||
double length = tube.getLength();
|
||||
double radius = tube.getRadius();
|
||||
double arc = Math.min(length, 2*radius) * 0.7;
|
||||
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
|
||||
|
||||
Shape[] s = new Shape[start.length];
|
||||
for (int i=0; i < start.length; i++) {
|
||||
s[i] = new RoundRectangle2D.Double(start[i].x,(start[i].y-radius),
|
||||
length,2*radius,arc,arc);
|
||||
}
|
||||
|
||||
Coordinate start = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
Shape[] s = {new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc)};
|
||||
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceOffset) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
MassObject tube = (MassObject)component;
|
||||
|
||||
double or = tube.getRadius();
|
||||
|
||||
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
|
||||
final Coordinate start = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
Shape[] s = new Shape[start.length];
|
||||
for (int i=0; i < start.length; i++) {
|
||||
s[i] = new Ellipse2D.Double((start[i].z-or),(start[i].y-or),2*or,2*or);
|
||||
}
|
||||
Shape[] s = {new Ellipse2D.Double((start.z-or), (start.y-or), 2*or, 2*or)};
|
||||
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
@ -12,36 +13,31 @@ import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
public class ParachuteShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
double length = tube.getLength();
|
||||
double radius = tube.getRadius();
|
||||
double arc = Math.min(length, 2*radius) * 0.7;
|
||||
Coordinate[] start = new Coordinate[]{transformation.transform( componentAbsoluteLocation)};
|
||||
|
||||
Coordinate start = transformation.transform( Coordinate.ZERO);
|
||||
|
||||
Shape[] s = new Shape[start.length];
|
||||
for (int i=0; i < start.length; i++) {
|
||||
s[i] = new RoundRectangle2D.Double(start[i].x, (start[i].y-radius), length, 2*radius, arc, arc);
|
||||
}
|
||||
Shape[] s = new Shape[1];
|
||||
|
||||
s[0] = new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc);
|
||||
|
||||
return RocketComponentShape.toArray( addSymbol(s), component);
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceOffset) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
double or = tube.getRadius();
|
||||
|
||||
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
|
||||
Coordinate[] start = transformation.transform(tube.toAbsolute(Coordinate.ZERO));
|
||||
|
||||
Shape[] s = new Shape[start.length];
|
||||
for (int i=0; i < start.length; i++) {
|
||||
|
@ -14,11 +14,8 @@ import net.sf.openrocket.util.Transformation;
|
||||
|
||||
public class RailButtonShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation) {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
RailButton btn = (RailButton)component;
|
||||
|
||||
final double rotation_rad = btn.getAngleOffset();
|
||||
@ -36,6 +33,11 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
final double innerHeightcos = innerHeight*cosr;
|
||||
final double flangeHeightcos = flangeHeight*cosr;
|
||||
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
System.err.println(String.format("Generating Shapes for RailButtons..."));
|
||||
System.err.println(String.format(" @ %s", instanceAbsoluteLocation));
|
||||
|
||||
|
||||
Path2D.Double path = new Path2D.Double();
|
||||
{// central pillar
|
||||
@ -51,7 +53,7 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+baseHeightcos), drawWidth, drawHeight), false);
|
||||
}
|
||||
|
||||
{// inner
|
||||
{// inner flange
|
||||
final double drawWidth = innerDiameter;
|
||||
final double drawHeight = innerDiameter*sinr;
|
||||
final Point2D.Double center = new Point2D.Double( instanceAbsoluteLocation.x, instanceAbsoluteLocation.y + baseHeightcos);
|
||||
@ -80,12 +82,9 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceOffset) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.RailButton btn = (net.sf.openrocket.rocketcomponent.RailButton)component;
|
||||
RailButton btn = (RailButton)component;
|
||||
|
||||
final double rotation_rad = btn.getAngleOffset();
|
||||
final double sinr = Math.sin(rotation_rad);
|
||||
@ -98,7 +97,8 @@ public class RailButtonShapes extends RocketComponentShape {
|
||||
final double outerRadius = outerDiameter/2;
|
||||
final double innerDiameter = btn.getInnerDiameter();
|
||||
final double innerRadius = innerDiameter/2;
|
||||
Coordinate[] inst = transformation.transform( btn.getLocations());
|
||||
|
||||
Coordinate[] inst = {transformation.transform(Coordinate.ZERO)};
|
||||
|
||||
Shape[] s = new Shape[inst.length];
|
||||
for (int i=0; i < inst.length; i++) {
|
||||
|
@ -2,19 +2,16 @@ package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.rocketcomponent.RingComponent;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
|
||||
public class RingComponentShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
|
||||
net.sf.openrocket.rocketcomponent.RingComponent tube = (net.sf.openrocket.rocketcomponent.RingComponent)component;
|
||||
Shape[] s;
|
||||
@ -26,24 +23,22 @@ public class RingComponentShapes extends RocketComponentShape {
|
||||
if ((outerRadius-innerRadius >= 0.0012) && (innerRadius > 0)) {
|
||||
// Draw outer and inner
|
||||
s = new Shape[] {
|
||||
TubeShapes.getShapesSide(transformation, instanceAbsoluteLocation, length, outerRadius),
|
||||
TubeShapes.getShapesSide(transformation, instanceAbsoluteLocation, length, innerRadius)
|
||||
TubeShapes.getShapesSide(transformation, length, outerRadius),
|
||||
TubeShapes.getShapesSide(transformation, length, innerRadius)
|
||||
};
|
||||
} else {
|
||||
// Draw only outer
|
||||
s = new Shape[] {
|
||||
TubeShapes.getShapesSide(transformation, instanceAbsoluteLocation, length, outerRadius)
|
||||
TubeShapes.getShapesSide(transformation, length, outerRadius)
|
||||
};
|
||||
}
|
||||
return RocketComponentShape.toArray( s, component);
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation) {
|
||||
net.sf.openrocket.rocketcomponent.RingComponent tube = (net.sf.openrocket.rocketcomponent.RingComponent)component;
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
RingComponent tube = (net.sf.openrocket.rocketcomponent.RingComponent)component;
|
||||
Shape[] s;
|
||||
|
||||
double outerRadius = tube.getOuterRadius();
|
||||
@ -51,12 +46,12 @@ public class RingComponentShapes extends RocketComponentShape {
|
||||
|
||||
if ((outerRadius-innerRadius >= 0.0012) && (innerRadius > 0)) {
|
||||
s = new Shape[] {
|
||||
TubeShapes.getShapesBack(transformation, instanceAbsoluteLocation, outerRadius),
|
||||
TubeShapes.getShapesBack(transformation, instanceAbsoluteLocation, innerRadius)
|
||||
TubeShapes.getShapesBack(transformation, outerRadius),
|
||||
TubeShapes.getShapesBack(transformation, innerRadius)
|
||||
};
|
||||
}else {
|
||||
s = new Shape[] {
|
||||
TubeShapes.getShapesBack(transformation, instanceAbsoluteLocation, outerRadius)
|
||||
TubeShapes.getShapesBack(transformation, outerRadius)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,8 @@ package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import java.awt.Shape;
|
||||
|
||||
import net.sf.openrocket.gui.scalefigure.RocketFigure;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.LineStyle;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
@ -51,20 +49,15 @@ public class RocketComponentShape {
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceOffset) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
// no-op
|
||||
Application.getExceptionHandler().handleErrorCondition("ERROR: RocketComponent.getShapesSide called with "
|
||||
+ component);
|
||||
return new RocketComponentShape[0];
|
||||
}
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceOffset) { // no-op
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
// no-op
|
||||
Application.getExceptionHandler().handleErrorCondition("ERROR: RocketComponent.getShapesBack called with "
|
||||
+component);
|
||||
return new RocketComponentShape[0];
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
@ -11,10 +12,8 @@ import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
public class ShockCordShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject massObj = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
@ -22,8 +21,7 @@ public class ShockCordShapes extends RocketComponentShape {
|
||||
double radius = massObj.getRadius();
|
||||
double arc = Math.min(length, 2*radius) * 0.7;
|
||||
|
||||
|
||||
Coordinate start = transformation.transform( componentAbsoluteLocation);
|
||||
Coordinate start = transformation.transform(Coordinate.ZERO);
|
||||
Shape[] s = new Shape[1];
|
||||
s[0] = new RoundRectangle2D.Double(start.x,(start.y-radius),
|
||||
length,2*radius,arc,arc);
|
||||
@ -32,17 +30,15 @@ public class ShockCordShapes extends RocketComponentShape {
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
double or = tube.getRadius();
|
||||
|
||||
Shape[] s = new Shape[1];
|
||||
Coordinate start = componentAbsoluteLocation;
|
||||
Coordinate start = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
s[0] = new Ellipse2D.Double((start.z-or),(start.y-or),2*or,2*or);
|
||||
|
||||
// Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
@ -11,10 +12,7 @@ import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
public class StreamerShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation ) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject massObj = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
@ -23,7 +21,7 @@ public class StreamerShapes extends RocketComponentShape {
|
||||
double arc = Math.min(length, 2*radius) * 0.7;
|
||||
|
||||
Shape[] s = new Shape[1];
|
||||
Coordinate frontCenter = componentAbsoluteLocation;
|
||||
Coordinate frontCenter = transformation.transform(Coordinate.ZERO);
|
||||
s[0] = new RoundRectangle2D.Double((frontCenter.x),(frontCenter.y-radius),
|
||||
length,2*radius,arc,arc);
|
||||
|
||||
@ -37,16 +35,14 @@ public class StreamerShapes extends RocketComponentShape {
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
double or = tube.getRadius();
|
||||
Shape[] s = new Shape[1];
|
||||
Coordinate center = componentAbsoluteLocation;
|
||||
Coordinate center = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
s[0] = new Ellipse2D.Double((center.z-or),(center.y-or),2*or,2*or);
|
||||
|
||||
// Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
@ -17,10 +18,8 @@ public class SymmetricComponentShapes extends RocketComponentShape {
|
||||
|
||||
// TODO: LOW: Uses only first component of cluster (not currently clusterable)
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
|
||||
SymmetricComponent c = (SymmetricComponent) component;
|
||||
|
||||
@ -79,7 +78,7 @@ public class SymmetricComponentShapes extends RocketComponentShape {
|
||||
//System.out.println("here");
|
||||
|
||||
final int len = points.size();
|
||||
Coordinate nose = componentAbsoluteLocation;
|
||||
Coordinate nose = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
// TODO: LOW: curved path instead of linear
|
||||
Path2D.Double path = new Path2D.Double();
|
||||
|
@ -12,24 +12,20 @@ import java.awt.geom.Path2D;
|
||||
|
||||
public class TransitionShapes extends RocketComponentShape {
|
||||
|
||||
// TODO: LOW: Uses only first component of cluster (not currently clusterable).
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceLocation) {
|
||||
return getShapesSide(component, transformation, instanceLocation, 1.0);
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
return getShapesSide(component, transformation, 1.0);
|
||||
}
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation,
|
||||
final double scaleFactor) {
|
||||
final RocketComponent component,
|
||||
final Transformation transformation,
|
||||
final double scaleFactor) {
|
||||
|
||||
|
||||
Transition transition = (Transition)component;
|
||||
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
RocketComponentShape[] mainShapes;
|
||||
|
||||
// Simpler shape for conical transition, others use the method from SymmetricComponent
|
||||
@ -49,27 +45,28 @@ public class TransitionShapes extends RocketComponentShape {
|
||||
|
||||
mainShapes = new RocketComponentShape[] { new RocketComponentShape( path, component) };
|
||||
} else {
|
||||
mainShapes = SymmetricComponentShapes.getShapesSide(component, transformation, instanceAbsoluteLocation);
|
||||
mainShapes = SymmetricComponentShapes.getShapesSide(component, transformation);
|
||||
}
|
||||
|
||||
Shape foreShoulder=null, aftShoulder=null;
|
||||
int arrayLength = mainShapes.length;
|
||||
|
||||
if (transition.getForeShoulderLength() > 0.0005) {
|
||||
Coordinate foreTransitionShoulderCenter = instanceAbsoluteLocation.sub( transition.getForeShoulderLength(), 0, 0);
|
||||
final Coordinate frontCenter = foreTransitionShoulderCenter; //transformation.transform( foreTransitionShoulderCenter);
|
||||
final double length = transition.getForeShoulderLength();
|
||||
final double radius = transition.getForeShoulderRadius();
|
||||
final double shoulderLength = transition.getForeShoulderLength();
|
||||
final double shoulderRadius = transition.getForeShoulderRadius();
|
||||
final Transformation offsetTransform = Transformation.getTranslationTransform(-transition.getForeShoulderLength(), 0, 0);
|
||||
final Transformation foreShoulderTransform = transformation.applyTransformation(offsetTransform);
|
||||
|
||||
foreShoulder = TubeShapes.getShapesSide( transformation, frontCenter, length, radius);
|
||||
foreShoulder = TubeShapes.getShapesSide( foreShoulderTransform, shoulderLength, shoulderRadius);
|
||||
arrayLength++;
|
||||
}
|
||||
if (transition.getAftShoulderLength() > 0.0005) {
|
||||
Coordinate aftTransitionShoulderCenter = instanceAbsoluteLocation.add( transition.getLength(), 0, 0);
|
||||
final Coordinate frontCenter = aftTransitionShoulderCenter; //transformation.transform( aftTransitionShoulderCenter );
|
||||
final double length = transition.getAftShoulderLength();
|
||||
final double radius = transition.getAftShoulderRadius();
|
||||
aftShoulder = TubeShapes.getShapesSide(transformation, frontCenter, length, radius);
|
||||
final double shoulderLength = transition.getAftShoulderLength();
|
||||
final double shoulderRadius = transition.getAftShoulderRadius();
|
||||
final Transformation offsetTransform = Transformation.getTranslationTransform(transition.getLength(), 0, 0);
|
||||
final Transformation aftShoulderTransform = transformation.applyTransformation(offsetTransform);
|
||||
|
||||
aftShoulder = TubeShapes.getShapesSide(aftShoulderTransform, shoulderLength, shoulderRadius);
|
||||
arrayLength++;
|
||||
}
|
||||
if (foreShoulder==null && aftShoulder==null)
|
||||
@ -92,17 +89,14 @@ public class TransitionShapes extends RocketComponentShape {
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.Transition transition = (net.sf.openrocket.rocketcomponent.Transition)component;
|
||||
Transition transition = (net.sf.openrocket.rocketcomponent.Transition)component;
|
||||
|
||||
double r1 = transition.getForeRadius();
|
||||
double r2 = transition.getAftRadius();
|
||||
|
||||
Coordinate center = componentAbsoluteLocation;
|
||||
final Coordinate center = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
Shape[] s = new Shape[2];
|
||||
s[0] = new Ellipse2D.Double((center.z-r1),(center.y-r1),2*r1,2*r1);
|
||||
|
@ -4,18 +4,17 @@ import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
|
||||
public class TubeFinSetShapes extends RocketComponentShape {
|
||||
|
||||
public static RocketComponentShape[] getShapesSide(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
|
||||
TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
|
||||
|
||||
int fins = finset.getFinCount();
|
||||
double length = finset.getLength();
|
||||
@ -47,12 +46,9 @@ public class TubeFinSetShapes extends RocketComponentShape {
|
||||
}
|
||||
|
||||
|
||||
public static RocketComponentShape[] getShapesBack(
|
||||
net.sf.openrocket.rocketcomponent.RocketComponent component,
|
||||
Transformation transformation,
|
||||
Coordinate componentAbsoluteLocation) {
|
||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||
|
||||
net.sf.openrocket.rocketcomponent.TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
|
||||
TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
|
||||
|
||||
int fins = finset.getFinCount();
|
||||
double outerradius = finset.getOuterRadius();
|
||||
|
@ -10,21 +10,19 @@ import net.sf.openrocket.util.Transformation;
|
||||
|
||||
public class TubeShapes extends RocketComponentShape {
|
||||
|
||||
public static Shape getShapesSide(
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation,
|
||||
final double length, final double radius ){
|
||||
public static Shape getShapesSide( final Transformation transformation, final double length, final double radius ){
|
||||
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
return new Rectangle2D.Double((instanceAbsoluteLocation.x), //x - the X coordinate of the upper-left corner of the newly constructed Rectangle2D
|
||||
(instanceAbsoluteLocation.y-radius), // y - the Y coordinate of the upper-left corner of the newly constructed Rectangle2D
|
||||
length, // w - the width of the newly constructed Rectangle2D
|
||||
2*radius); // h - the height of the newly constructed Rectangle2D
|
||||
}
|
||||
|
||||
public static Shape getShapesBack(
|
||||
Transformation transformation,
|
||||
Coordinate instanceAbsoluteLocation,
|
||||
final double radius ) {
|
||||
public static Shape getShapesBack( final Transformation transformation, final double radius ) {
|
||||
|
||||
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
|
||||
|
||||
return new Ellipse2D.Double((instanceAbsoluteLocation.z-radius), (instanceAbsoluteLocation.y-radius), 2*radius, 2*radius);
|
||||
}
|
||||
|
@ -15,22 +15,21 @@ import java.awt.geom.NoninvertibleTransformException;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.sf.openrocket.gui.figureelements.FigureElement;
|
||||
import net.sf.openrocket.gui.rocketfigure.RocketComponentShape;
|
||||
import net.sf.openrocket.gui.scalefigure.RocketPanel.VIEW_TYPE;
|
||||
import net.sf.openrocket.gui.util.ColorConversion;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
@ -192,8 +191,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
updateCanvasSize();
|
||||
updateTransform();
|
||||
|
||||
figureShapes.clear();
|
||||
updateShapeTree( this.figureShapes, rocket, this.axialRotation, Coordinate.ZERO);
|
||||
updateShapes(this.figureShapes);
|
||||
|
||||
g2.transform(projection);
|
||||
|
||||
@ -336,60 +334,29 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
return l.toArray(new RocketComponent[0]);
|
||||
}
|
||||
|
||||
// NOTE: Recursive function
|
||||
private ArrayList<RocketComponentShape> updateShapeTree(
|
||||
ArrayList<RocketComponentShape> allShapes, // output parameter
|
||||
final RocketComponent comp,
|
||||
final Transformation parentTransform,
|
||||
final Coordinate parentLocation){
|
||||
private void updateShapes(ArrayList<RocketComponentShape> allShapes) {
|
||||
// source input
|
||||
final FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||
|
||||
// allShapes is an output buffer -- it stores all the generated shapes
|
||||
allShapes.clear();
|
||||
|
||||
for(Entry<RocketComponent, ArrayList<InstanceContext>> entry: config.getActiveInstances().entrySet() ) {
|
||||
final RocketComponent comp = entry.getKey();
|
||||
|
||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||
|
||||
final int instanceCount = comp.getInstanceCount();
|
||||
Coordinate[] instanceLocations = comp.getInstanceLocations();
|
||||
instanceLocations = parentTransform.transform( instanceLocations );
|
||||
double[] instanceAngles = comp.getInstanceAngles();
|
||||
if( instanceLocations.length != instanceAngles.length ){
|
||||
throw new ArrayIndexOutOfBoundsException(String.format("lengths of location array (%d) and angle arrays (%d) differs! (in: %s) ", instanceLocations.length, instanceAngles.length, comp.getName()));
|
||||
}
|
||||
|
||||
// iterate over the aggregated instances *for the whole* tree.
|
||||
for( int index = 0; instanceCount > index ; ++index ){
|
||||
final double currentAngle = instanceAngles[index];
|
||||
|
||||
Transformation currentTransform = parentTransform;
|
||||
if( 0.00001 < Math.abs( currentAngle )) {
|
||||
Transformation currentAngleTransform = Transformation.rotate_x( currentAngle );
|
||||
currentTransform = currentAngleTransform.applyTransformation( parentTransform );
|
||||
}
|
||||
|
||||
Coordinate currentLocation = parentLocation.add( instanceLocations[index] );
|
||||
|
||||
// if(FinSet.class.isAssignableFrom(comp.getClass())) {
|
||||
// System.err.println(String.format("@%s: %s -- inst: [%d/%d]", comp.getClass().getSimpleName(), comp.getName(), index+1, instanceCount));
|
||||
//
|
||||
// // FlightConfiguration config = this.rocket.getSelectedConfiguration();
|
||||
// // System.err.println(String.format(" -- stage: %d, active: %b, config: (%d) %s", comp.getStageNumber(), config.isComponentActive(comp), config.instanceNumber, config.getId()));
|
||||
// System.err.println(String.format(" -- %s + %s = %s", parentLocation.toString(), instanceLocations[index].toString(), currentLocation.toString()));
|
||||
// if( 0.00001 < Math.abs( currentAngle )) {
|
||||
// System.err.println(String.format(" -- at: %6.4f radians", currentAngle));
|
||||
// }
|
||||
// }
|
||||
|
||||
// generate shape for this component, if active
|
||||
if( this.rocket.getSelectedConfiguration().isComponentActive( comp )){
|
||||
allShapes = addThisShape( allShapes, this.currentViewType, comp, currentLocation, currentTransform);
|
||||
}
|
||||
|
||||
// recurse into component's children
|
||||
for( RocketComponent child: comp.getChildren() ){
|
||||
// draw a tree for each instance subcomponent
|
||||
updateShapeTree( allShapes, child, currentTransform, currentLocation );
|
||||
}
|
||||
}
|
||||
|
||||
return allShapes;
|
||||
for(InstanceContext context: contextList ) {
|
||||
final Transformation currentTransform = this.axialRotation.applyTransformation(context.transform);
|
||||
|
||||
// generate shape for this component, if active
|
||||
if( context.active ) {
|
||||
allShapes = addThisShape( allShapes, this.currentViewType, comp, currentTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the shapes required to draw the component.
|
||||
*
|
||||
@ -401,12 +368,11 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
ArrayList<RocketComponentShape> allShapes, // this is the output parameter
|
||||
final RocketPanel.VIEW_TYPE viewType,
|
||||
final RocketComponent component,
|
||||
final Coordinate instanceOffset,
|
||||
final Transformation transformation) {
|
||||
Reflection.Method m;
|
||||
|
||||
if(( component instanceof Rocket)||( component instanceof ComponentAssembly )){
|
||||
// no-op; no shapes here, either.
|
||||
// no-op; no shapes here
|
||||
return allShapes;
|
||||
}
|
||||
|
||||
@ -414,12 +380,12 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
switch (viewType) {
|
||||
case SideView:
|
||||
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesSide",
|
||||
RocketComponent.class, Transformation.class, Coordinate.class);
|
||||
RocketComponent.class, Transformation.class);
|
||||
break;
|
||||
|
||||
case BackView:
|
||||
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesBack",
|
||||
RocketComponent.class, Transformation.class, Coordinate.class);
|
||||
RocketComponent.class, Transformation.class);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -433,14 +399,13 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
}
|
||||
|
||||
|
||||
RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation, instanceOffset);
|
||||
RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation);
|
||||
for ( RocketComponentShape curShape : returnValue ){
|
||||
allShapes.add( curShape );
|
||||
}
|
||||
return allShapes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the bounds of the drawn subject in Model-Space
|
||||
|
@ -620,7 +620,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
length = maxX - minX;
|
||||
}
|
||||
|
||||
for (RocketComponent c : curConfig.getActiveComponents()) {
|
||||
for (RocketComponent c : curConfig.getAllComponents()) {
|
||||
if (c instanceof SymmetricComponent) {
|
||||
double d1 = ((SymmetricComponent) c).getForeRadius() * 2;
|
||||
double d2 = ((SymmetricComponent) c).getAftRadius() * 2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user