Skip to content

Commit

Permalink
Merge pull request vZome#907 from vorth/line-reflection-tool
Browse files Browse the repository at this point in the history
David Hall's line reflection tool
  • Loading branch information
vorth authored Jul 24, 2024
2 parents 3afe819 + e422f0e commit c82cd88
Show file tree
Hide file tree
Showing 17 changed files with 273 additions and 12 deletions.
63 changes: 63 additions & 0 deletions core/src/main/java/com/vzome/core/construction/LineReflection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.vzome.core.construction;

import com.vzome.core.algebra.AlgebraicNumber;
import com.vzome.core.algebra.AlgebraicVector;
import com.vzome.core.algebra.AlgebraicVectors;

public class LineReflection extends Transformation {
private final AlgebraicNumber two;
private final Line mMirrorLine;
private final AlgebraicVector mStart;
private final AlgebraicVector mEnd;

public LineReflection(Segment axis) {
super(axis.field);
two = field .createRational(2);
mMirrorLine = new LineExtensionOfSegment(axis);
mStart = axis.getStart();
mEnd = axis.getEnd();
// DJH: Note that PointReflection and PlaneReflection (and other Constructions)
// call mapParamsToState() at the end of their c'tor.
// mapParamsToState() in turn, calls setStateVariables().
// I don't really understand the purpose of these two methods,
// so I haven't followed that pattern for the LineReflection class.
// I think that pattern is probably only necessary for linear transformations
// that make use of the mTransform matrix and the mOffset vector in the base class.
// This LineReflection class is not a linear transformation
// so it doesn't make use any of that base class functionality.
// Therefore I won't mess with overriding or calling mapParamsToState().
// I'm not sure what implication this may have down the road
// so I'm just making a note of it here for now.
}

@Override
protected final boolean mapParamsToState() {
return true;
}

@Override
public AlgebraicVector transform(AlgebraicVector arg) {
AlgebraicVector norm1 = AlgebraicVectors.getNormal(mStart, mEnd, arg);
if(norm1.isOrigin()) {
// arg is collinear with mMirrorLine so return it unchanged
return arg;
}
AlgebraicVector norm2 = AlgebraicVectors.getNormal(mStart, mEnd, norm1);
// norm2 is a vector that is orthogonal to mMirrorLine
// and is on the plane formed by mMirrorLine and v,
// so the intersection of mMirrorLine and line2
// is the point on mMirrorLine that is closest to v.

// I'm just going to use a local LineLineIntersectionPoint
// to do the work instead of duplicating the math.
// This approach has been used in StrutIntersection and PolygonPolygonProjectionToSegment
Line line2 = new LineFromPointAndVector( arg, norm2 );
Point point = new LineLineIntersectionPoint(mMirrorLine, line2 );
AlgebraicVector intersection = point.getLocation();

// double the distance to the intersection point to get the mirror translation vector.
AlgebraicVector translation = intersection.minus(arg).scale(two);
// return the translated input
return arg.plus(translation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.vzome.core.math.symmetry.WythoffConstruction;
import com.vzome.core.tools.BookmarkToolFactory;
import com.vzome.core.tools.InversionToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.ModuleToolFactory;
Expand Down Expand Up @@ -122,7 +123,8 @@ public void registerToolFactories( Map<String, Factory> toolFactories, ToolsMode
toolFactories .put( "ScalingTool", new ScalingToolFactory( tools, null ) );

toolFactories .put( "InversionTool", new InversionToolFactory( tools ) );
toolFactories .put( "MirrorTool", new MirrorToolFactory( tools ) );
toolFactories .put( "LineReflectionTool", new LineReflectionToolFactory( tools ) );
toolFactories .put( "MirrorTool", new MirrorToolFactory( tools ) );
toolFactories .put( "TranslationTool", new TranslationToolFactory( tools ) );
toolFactories .put( "ProjectionTool", new ProjectionToolFactory( tools ) );
toolFactories .put( "PerspectiveProjectionTool", new PerspectiveProjectionToolFactory( tools ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.vzome.core.editor.SymmetryPerspective;
import com.vzome.core.editor.ToolsModel;
import com.vzome.core.tools.AxialSymmetryToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.RotationToolFactory;
Expand Down Expand Up @@ -82,6 +83,7 @@ public List<Tool.Factory> createToolFactories( Tool.Kind kind, ToolsModel tools

case SYMMETRY:
result .add( new SymmetryToolFactory( tools, this .symmetry ) );
result .add( new LineReflectionToolFactory( tools ));
result .add( new MirrorToolFactory( tools ) );
result .add( new AxialSymmetryToolFactory( tools, this .symmetry ) );
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.vzome.core.tools.AxialSymmetryToolFactory;
import com.vzome.core.tools.IcosahedralToolFactory;
import com.vzome.core.tools.InversionToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.PerspectiveProjectionToolFactory;
Expand Down Expand Up @@ -105,6 +106,7 @@ public List<Tool.Factory> createToolFactories(Tool.Kind kind, ToolsModel tools)
result.add(new IcosahedralToolFactory(tools, icosaSymm));
result.add(new TetrahedralToolFactory(tools, icosaSymm));
result.add(new InversionToolFactory(tools));
result.add( new LineReflectionToolFactory(tools));
result.add(new MirrorToolFactory(tools));
result.add(new AxialSymmetryToolFactory(tools, icosaSymm));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.vzome.core.math.symmetry.OctahedralSymmetry;
import com.vzome.core.tools.AxialSymmetryToolFactory;
import com.vzome.core.tools.InversionToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.OctahedralToolFactory;
Expand Down Expand Up @@ -42,7 +43,8 @@ public List<Tool.Factory> createToolFactories( Tool.Kind kind, ToolsModel tools
result .add( new OctahedralToolFactory( tools, this .symmetry ) );
result .add( new TetrahedralToolFactory( tools, this .symmetry ) );
result .add( new InversionToolFactory( tools ) );
result .add( new MirrorToolFactory( tools ) );
result .add( new LineReflectionToolFactory( tools ) );
result .add( new MirrorToolFactory( tools ) );
result .add( new AxialSymmetryToolFactory( tools, this .symmetry ) );
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.vzome.core.tools.AxialSymmetryToolFactory;
import com.vzome.core.tools.IcosahedralToolFactory;
import com.vzome.core.tools.InversionToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.ProjectionToolFactory;
Expand Down Expand Up @@ -109,6 +110,7 @@ public List<Tool.Factory> createToolFactories(Tool.Kind kind, ToolsModel tools)
// which is always the case when PolygonField.getField().isEven().
result .add( new InversionToolFactory( tools ) );
}
result.add(new LineReflectionToolFactory(tools));
result.add(new MirrorToolFactory(tools));
result.add(new AxialSymmetryToolFactory(tools, this.symmetry));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.vzome.core.math.symmetry.Symmetry;
import com.vzome.core.tools.AxialSymmetryToolFactory;
import com.vzome.core.tools.InversionToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.ProjectionToolFactory;
Expand Down Expand Up @@ -114,6 +115,7 @@ public List<Tool.Factory> createToolFactories( Tool.Kind kind, ToolsModel tools
case SYMMETRY:
result .add( new SymmetryToolFactory( tools, this .symmetry ) );
result .add( new InversionToolFactory( tools ) );
result. add( new LineReflectionToolFactory( tools ));
result .add( new MirrorToolFactory( tools ) );
result .add( new AxialSymmetryToolFactory( tools, this .symmetry ) );
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.vzome.core.math.symmetry.Symmetry;
import com.vzome.core.tools.AxialSymmetryToolFactory;
import com.vzome.core.tools.InversionToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.OctahedralToolFactory;
Expand Down Expand Up @@ -148,6 +149,7 @@ public List<Tool.Factory> createToolFactories( Tool.Kind kind, ToolsModel tools
result .add( new OctahedralToolFactory( tools, this .symmetry ) );
result .add( new TetrahedralToolFactory( tools, this .symmetry ) );
result .add( new InversionToolFactory( tools ) );
result .add( new LineReflectionToolFactory( tools ));
result .add( new MirrorToolFactory( tools ) );
result .add( new AxialSymmetryToolFactory( tools, this .symmetry ) );
break;
Expand Down
51 changes: 51 additions & 0 deletions core/src/main/java/com/vzome/core/tools/LineReflectionTool.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.vzome.core.tools;

import com.vzome.core.construction.LineReflection;
import com.vzome.core.construction.Segment;
import com.vzome.core.construction.Transformation;
import com.vzome.core.editor.ToolsModel;
import com.vzome.core.model.Manifestation;
import com.vzome.core.model.Strut;

public class LineReflectionTool extends TransformationTool {
public LineReflectionTool(String id, ToolsModel tools) {
super(id, tools);
this. setCopyColors( false );
}

@Override
protected String checkSelection(boolean prepareTool) {
Segment axis = null;
for (Manifestation man : mSelection) {
if (prepareTool) {
unselect(man);
}
if (man instanceof Strut) {
if (axis != null) {
if (prepareTool) {
break;
} else {
return "Only one mirror axis strut may be selected";
}
}
axis = (Segment) ((Strut) man).getFirstConstruction();
}
}
if (axis == null) {
return "line reflection tool requires a single strut";
}

if (prepareTool) {
this.transforms = new Transformation[1];
transforms[0] = new LineReflection(axis);
}

return null;
}

@Override
protected String getXmlElementName() {
return "LineReflectionTool";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.vzome.core.tools;

import com.vzome.core.editor.AbstractToolFactory;
import com.vzome.core.editor.Tool;
import com.vzome.core.editor.ToolsModel;
import com.vzome.core.editor.api.Selection;

public class LineReflectionToolFactory extends AbstractToolFactory {
static final String ID = "line reflection";
static final String LABEL = "Create a line reflection tool";
static final String TOOLTIP = "<p>"
+ "Each tool duplicates the selection by reflecting<br>"
+ "each object in a line. To create a tool,<br>"
+ "define the mirror line by selecting a strut.<br>"
+ "</p>";

public LineReflectionToolFactory(ToolsModel tools) {
super(tools, null, ID, LABEL, TOOLTIP);
}

@Override
public Tool createToolInternal(String id) {
return new LineReflectionTool(id, getToolsModel());
}

@Override
protected boolean countsAreValid(int total, int balls, int struts, int panels) {
return (total == 1 && struts == 1);
}

@Override
protected boolean bindParameters(Selection selection) {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.vzome.core.math.symmetry.WythoffConstruction.Listener;
import com.vzome.core.tools.AxialSymmetryToolFactory;
import com.vzome.core.tools.InversionToolFactory;
import com.vzome.core.tools.LineReflectionToolFactory;
import com.vzome.core.tools.LinearMapToolFactory;
import com.vzome.core.tools.MirrorToolFactory;
import com.vzome.core.tools.ProjectionToolFactory;
Expand Down Expand Up @@ -138,6 +139,7 @@ public List<Tool.Factory> createToolFactories( Tool.Kind kind, ToolsModel tools
case SYMMETRY:
result .add( new SymmetryToolFactory( tools, pentaSymm ) );
result .add( new InversionToolFactory(tools));
result .add( new LineReflectionToolFactory( tools ) );
result .add( new MirrorToolFactory( tools ) );
result .add( new AxialSymmetryToolFactory( tools, pentaSymm ) );
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vzome:vZome xmlns:vzome="http://xml.vzome.com/vZome/4.0.0/" buildNumber="4242" field="golden" version="7.1">
<EditHistory editNumber="13" lastStickyEdit="13">
<StrutCreation anchor="0 0 0 0 0 0" dir="red" index="1" len="5 8"/>
<SelectManifestation endSegment="0 0 8 13 5 8" startSegment="0 0 0 0 0 0"/>
<LineReflectionTool name="tool-0"/>
<Delete/>
<SelectManifestation point="0 0 8 13 5 8"/>
<ApplyTool copyColors="true" name="point reflection.builtin/reflection through origin" selectInputs="true"/>
<JoinPoints closedLoop="false"/>
<StrutCreation anchor="0 0 0 0 0 0" index="0" len="2 2"/>
<StrutCreation anchor="2 2 0 0 0 0" index="54" len="2 4"/>
<SelectAll originLast="true"/>
<ApplyTool copyColors="false" name="tool-0" selectInputs="true"/>
<DeselectAll/>
<Snapshot id="0"/>
</EditHistory>
<notes>
<page snapshot="0" title="Line Reflection Tool Icon">
<ViewModel distance="55.08510971069336" far="110.17005920410156" near="0.13771291077136993" parallel="false" stereoAngle="0.0" width="24.788301467895508">
<LookAtPoint x="0.0" y="0.0" z="0.0"/>
<UpDirection x="-0.001430845819413662" y="-0.9478051662445068" z="-0.31886541843414307"/>
<LookDirection x="0.6607220768928528" y="0.23845131695270538" z="-0.7117519378662109"/>
</ViewModel>
<content xml:space="preserve"/>
</page>
</notes>
<sceneModel ambientLight="41,41,41" background="153,153,153">
<directionalLight color="235,235,228" x="1.0" y="-1.0" z="-1.0"/>
<directionalLight color="228,228,235" x="-1.0" y="0.0" z="0.0"/>
<directionalLight color="30,30,30" x="0.0" y="0.0" z="-1.0"/>
</sceneModel>
<Viewing>
<ViewModel distance="55.08510971069336" far="110.17005920410156" near="0.13771291077136993" parallel="false" stereoAngle="0.0" width="24.788301467895508">
<LookAtPoint x="0.0" y="0.0" z="0.0"/>
<UpDirection x="-0.001430845819413662" y="-0.9478051662445068" z="-0.31886541843414307"/>
<LookDirection x="0.6607220768928528" y="0.23845131695270538" z="-0.7117519378662109"/>
</ViewModel>
</Viewing>
<SymmetrySystem name="icosahedral" renderingStyle="solid connectors">
<Direction color="0,142,194" name="blue" orbit="[[0,0,1],[0,0,1]]"/>
<Direction color="0,153,63" name="green" orbit="[[2,-1,1],[5,-3,1]]"/>
<Direction color="154,117,74" name="sand" orbit="[[-8,5,1],[5,-3,1]]"/>
<Direction color="255,255,255" name="1" orbit="[[-8,6,5],[-4,3,5]]" prototype="1 0 1/5 -2/5 -3/5 6/5"/>
<Direction color="18,73,48" name="spruce" orbit="[[-5,4,11],[-5,4,11]]"/>
<Direction color="184,134,11" name="2" orbit="[[1,0,2],[0,0,1]]" prototype="1 0 -4/5 3/5 7/5 1/5"/>
<Direction color="255,255,255" name="0" orbit="[[-7,5,11],[0,0,1]]" prototype="1 0 -3/5 6/5 -1/5 2/5"/>
<Direction color="217,18,24" name="red" orbit="[[-1,1,1],[0,0,1]]"/>
<Direction color="255,126,106" name="coral" orbit="[[-3,2,2],[-1,1,2]]"/>
<Direction color="50,50,50" name="black" orbit="[[-2,3,11],[-7,5,11]]"/>
<Direction color="117,0,50" name="maroon" orbit="[[5,-3,1],[0,0,1]]"/>
<Direction color="239,245,61" name="sulfur" orbit="[[-1,1,3],[0,0,1]]"/>
<Direction color="255,179,26" name="yellow" orbit="[[0,0,1],[2,-1,1]]"/>
<Direction color="255,51,143" name="rose" orbit="[[0,0,1],[-4,3,5]]"/>
<Direction color="0,179,161" name="turquoise" orbit="[[2,-1,2],[-3,2,2]]"/>
<Direction color="116,195,0" name="apple" orbit="[[2,-1,3],[-1,1,3]]"/>
<Direction color="136,37,0" name="cinnamon" orbit="[[5,-3,2],[2,-1,2]]"/>
<Direction color="125,54,211" name="purple" orbit="[[2,-1,1],[0,0,1]]"/>
<Direction color="235,82,0" name="orange" orbit="[[-4,3,5],[3,-1,5]]"/>
<Direction color="0,0,153" name="navy" orbit="[[-1,1,2],[2,-1,2]]"/>
<Direction color="107,53,26" name="brown" orbit="[[2,-1,3],[5,-3,3]]"/>
<Direction color="175,135,255" name="lavender" orbit="[[-3,2,1],[-3,2,1]]"/>
<Direction color="100,113,0" name="olive" orbit="[[3,-1,5],[0,0,1]]"/>
</SymmetrySystem>
<OtherSymmetries>
<SymmetrySystem name="octahedral" renderingStyle="trapezoids">
<Direction color="0,142,194" name="blue" orbit="[[0,0,1],[0,0,1]]"/>
<Direction color="175,135,255" name="lavender" orbit="[[1,2,1],[-1,0,1]]"/>
<Direction color="0,179,161" name="turquoise" orbit="[[-1,2,1],[1,-2,1]]"/>
<Direction color="50,50,50" name="black" orbit="[[0,1,1],[1,-1,1]]"/>
<Direction color="0,153,63" name="green" orbit="[[0,0,1],[-1,0,1]]"/>
<Direction color="100,113,0" name="olive" orbit="[[1,0,1],[3,-2,1]]"/>
<Direction color="117,0,50" name="maroon" orbit="[[-1,2,1],[1,0,1]]"/>
<Direction color="107,53,26" name="brown" orbit="[[1,0,1],[-2,0,1]]"/>
<Direction color="255,179,26" name="yellow" orbit="[[1,0,1],[-1,0,1]]"/>
<Direction color="217,18,24" name="red" orbit="[[-1,1,1],[0,0,1]]"/>
<Direction color="125,54,211" name="purple" orbit="[[0,0,1],[2,-1,1]]"/>
</SymmetrySystem>
</OtherSymmetries>
<Tools>
<Tool copyColors="false" deleteInputs="false" id="tool-0" label="line reflection 0" selectInputs="true"/>
</Tools>
</vzome:vZome>
3 changes: 3 additions & 0 deletions core/src/regression/files/sniff-test.vZome-files
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,6 @@ format-2.1.0-models.vZome-files

#SelectCoplanar can now be called from a panel's context menu
2023/11-Nov/15-David-SelectCoplanar/SelectCoplanar-from-context-menu.vZome

#LineReflection Tool Icon is also the regression file for the new tool
2024/07-Jul/22-David-LineReflection/LineReflectionToolIcon.vZome
Loading

0 comments on commit c82cd88

Please sign in to comment.