2
GeoGebra - Dynamic Mathematics for Everyone
3
http://www.geogebra.org
5
This file is part of GeoGebra.
7
This program is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by
9
the Free Software Foundation.
13
package geogebra.kernel;
15
import geogebra.kernel.arithmetic.ExpressionNode;
16
import geogebra.kernel.arithmetic.ExpressionValue;
17
import geogebra.kernel.arithmetic.Function;
18
import geogebra.main.Application;
20
import java.util.ArrayList;
21
import java.util.HashMap;
25
* Algorithm to invoke a specific macro.
30
public class AlgoMacro extends AlgoElement
31
implements EuclidianViewAlgo {
33
private static final long serialVersionUID = 1L;
37
// macro construction, its input and output used by this algo
38
private GeoElement [] macroInput, macroOutput;
40
// maps macro geos to algo geos
41
private HashMap macroToAlgoMap;
43
// all keys of macroToAlgoMap that are not part of macroInput
44
private ArrayList macroOutputAndReferencedGeos;
45
private ArrayList algoOutputAndReferencedGeos; // for efficiency, see getMacroConstructionState()
48
* Creates a new algorithm that applies a macro to the
49
* given input objects.
51
public AlgoMacro(Construction cons, String [] labels, Macro macro, GeoElement [] input) {
57
this.macroInput = macro.getMacroInput();
58
this.macroOutput = macro.getMacroOutput();
60
// register algorithm with macro
61
macro.registerAlgorithm(this);
63
// create copies for the output objects
64
createOutputObjects();
66
// initialize the mapping between macro geos and algo geos
72
// check if macro construction has euclidianAlgos
73
if (macro.getMacroConstruction().hasEuclidianViewAlgos()) {
74
cons.registerEuclidianViewAlgo(this);
77
GeoElement.setLabels(labels, output);
80
public void remove() {
81
macro.unregisterAlgorithm(this);
85
protected String getClassName() {
89
String getCommandName() {
90
return macro.getCommandName();
93
protected void setInputOutput() {
97
final protected void compute() {
99
// set macro geos to algo geos state
100
setMacroConstructionState();
102
// update all algorithms of macro-construction
103
macro.getMacroConstruction().updateAllAlgorithms();
105
// set algo geos to macro geos state
106
getMacroConstructionState();
108
} catch (Exception e) {
109
Application.debug("AlgoMacro compute():\n");
111
for (int i=0; i < output.length; i++) {
112
output[i].setUndefined();
117
final public String toString() {
118
return getCommandDescription();
122
* Returns true when macroGeo is part of macroInput.
124
private boolean isMacroInputObject(GeoElement macroGeo) {
125
for (int i=0; i < macroInput.length; i++) {
126
if (macroGeo == macroInput[i])
134
* Sets macro geos to the current state of algo geos.
136
final void setMacroConstructionState() {
137
// set input objects of macro construction
138
for (int i=0; i < macroInput.length; i++) {
139
macroInput[i].set(input[i]);
140
macroInput[i].setRealLabel(input[i].getLabel());
141
//Application.debug("SET INPUT object: " + input[i] + " => " + macroInput[i]);
147
* Sets algo geos to the current state of macro geos.
149
final void getMacroConstructionState() {
150
// for efficiency: instead of lookups in macroToAlgoMap
151
// we use an array list algoOutputAndReferencedGeos with corresponding macro and algo geos
152
int size = macroOutputAndReferencedGeos.size();
153
for (int i=0; i < size; i++) {
154
GeoElement macroGeo = (GeoElement) macroOutputAndReferencedGeos.get(i);
155
GeoElement algoGeo = (GeoElement) algoOutputAndReferencedGeos.get(i);
156
if (macroGeo.isDefined()) {
157
algoGeo.set(macroGeo);
159
else algoGeo.setUndefined();
160
// System.out.println("RESULT from macro: " + macroGeo + "\n => " + algoGeo);
161
// System.out.println(" macroGeo kernel: " + macroGeo.kernel + ", printFigures: " + macroGeo.kernel.getPrintFigures());
162
// System.out.println(" algoGeo kernel: " + algoGeo.kernel + ", printFigures: " + algoGeo.kernel.getPrintFigures());
167
// int size = macroOutputAndReferencedGeos.size();
168
// for (int i=0; i < size; i++) {
169
// GeoElement macroGeo = (GeoElement) macroOutputAndReferencedGeos.get(i);
170
// GeoElement algoGeo = (GeoElement) macroToAlgoMap.get(macroGeo);
171
// algoGeo.set(macroGeo);
173
// Application.debug("RESULT from macro: " + macroGeo + " => " + algoGeo);
180
* Creates the output objects of this macro algorithm
182
private void createOutputObjects() {
183
output = new GeoElement[macroOutput.length];
185
for (int i=0; i < macroOutput.length; i++) {
186
// copy output object of macro and make the copy part of this construction
187
output[i] = macroOutput[i].copyInternal(cons);
188
output[i].setUseVisualDefaults(false);
189
output[i].setVisualStyle(macroOutput[i]);
190
output[i].setAlgoMacroOutput(true);
195
* Inits the mapping of macro geos to algo geos construction.
196
* The map is used to set and get the state of the macro construction in compute()
197
* and to make sure that all output geos of the algorithm and all
198
* their references (e.g. the start point of a ray) are part of the algorithm's
201
private void initMap() {
202
macroToAlgoMap = new HashMap();
203
macroOutputAndReferencedGeos = new ArrayList();
204
algoOutputAndReferencedGeos = new ArrayList();
207
// map macro input to algo input
208
for (int i=0; i < macroInput.length; i++) {
209
map(macroInput[i], input[i]);
213
// map macro output to algo output
214
for (int i=0; i < macroOutput.length; i++) {
215
map(macroOutput[i], output[i]);
217
// SPECIAL REFERENCES of output
218
// make sure all algo-output objects reference objects in their own construction
219
// note: we do this in an extra loop to make sure we don't create output objects twice
220
for (int i=0; i < macroOutput.length; i++) {
221
initSpecialReferences(macroOutput[i], output[i]);
226
* Adds a (macroGeo, algoGeo) pair to the map.
228
private void map(GeoElement macroGeo, GeoElement algoGeo) {
229
if (macroToAlgoMap.get(macroGeo) == null) {
230
// map macroGeo to algoGeo
231
macroToAlgoMap.put(macroGeo, algoGeo);
233
if (!isMacroInputObject(macroGeo)) {
234
macroOutputAndReferencedGeos.add(macroGeo);
235
// for efficiency: to avoid lookups in macroToAlgoMap
236
algoOutputAndReferencedGeos.add(algoGeo);
242
* Returns a GeoElement in this algo's construction
243
* that corresponds to the given macroGeo from the macro construction.
244
* If a macro-geo is not yet
245
* mapped to an algo-geo, a new algo-geo is created and added to
246
* the map automatically.
248
private GeoElement getAlgoGeo(GeoElement macroGeo) {
249
if (macroGeo == null) return null;
250
GeoElement algoGeo = (GeoElement) macroToAlgoMap.get(macroGeo);
252
// if we don't have a corresponding GeoElement in our map yet,
253
// create a new geo and update the map
254
if (algoGeo == null) {
255
algoGeo = createAlgoCopy(macroGeo);
256
map(macroGeo, algoGeo);
263
* Creates a new algo-geo in this construction that is copy of macroGeo from
264
* the macro construction.
266
private GeoElement createAlgoCopy(GeoElement macroGeo) {
267
GeoElement algoGeo = macroGeo.copyInternal(cons);
273
* Some GeoElement types need special settings as they reference other
274
* GeoElement objects. We need to make sure that algoGeo
275
* only reference objects in its own construction.
277
private void initSpecialReferences(GeoElement macroGeo, GeoElement algoGeo) {
279
switch (macroGeo.getGeoClassType()) {
280
case GeoElement.GEO_CLASS_FUNCTION:
281
initFunction(((GeoFunction) algoGeo).getFunction());
284
case GeoElement.GEO_CLASS_FUNCTIONCONDITIONAL:
285
// done by set() in GeoFunctionConditional
286
// actually a GeoFunctionConditional consists of three GeoFunction objects,
287
// so initFunction() is eventually used for them
290
case GeoElement.GEO_CLASS_LIST:
291
initList((GeoList) macroGeo, (GeoList) algoGeo);
294
case GeoElement.GEO_CLASS_LINE:
295
initLine((GeoLine) macroGeo, (GeoLine) algoGeo);
298
case GeoElement.GEO_CLASS_POLYGON:
299
initPolygon((GeoPolygon) macroGeo, (GeoPolygon) algoGeo);
302
case GeoElement.GEO_CLASS_CONIC:
303
initConic((GeoConic) macroGeo, (GeoConic) algoGeo);
306
case GeoElement.GEO_CLASS_TEXT:
307
case GeoElement.GEO_CLASS_VECTOR:
308
case GeoElement.GEO_CLASS_IMAGE:
309
initLocateable((Locateable) macroGeo, (Locateable) algoGeo);
313
// no special treatment necessary at the moment
314
// case GeoElement.GEO_CLASS_ANGLE:
315
// case GeoElement.GEO_CLASS_BOOLEAN:
316
// case GeoElement.GEO_CLASS_CONICPART:
317
// case GeoElement.GEO_CLASS_LOCUS:
318
// case GeoElement.GEO_CLASS_NUMERIC:
319
// case GeoElement.GEO_CLASS_POINT:
320
// case GeoElement.GEO_CLASS_AXIS:
321
// case GeoElement.GEO_CLASS_RAY:
322
// case GeoElement.GEO_CLASS_SEGMENT:
323
// case GeoElement.GEO_CLASS_POLYGON:
328
* Makes sure that the start and end point of a line are
329
* in its construction (if the line has this kind of information).
331
private void initLine(GeoLine macroLine, GeoLine line) {
332
GeoPoint startPoint = (GeoPoint) getAlgoGeo(macroLine.getStartPoint());
333
GeoPoint endPoint = (GeoPoint) getAlgoGeo(macroLine.getEndPoint());
334
line.setStartPoint(startPoint);
335
line.setEndPoint(endPoint);
339
* Makes sure that all points on conic are
340
* in its construction.
342
private void initConic(GeoConic macroConic, GeoConic conic) {
343
ArrayList macroPoints = macroConic.getPointsOnConic();
344
if (macroPoints == null) return;
346
int size = macroPoints.size();
347
ArrayList points = new ArrayList(size);
348
for (int i=0; i < size; i++) {
349
points.add(getAlgoGeo((GeoElement) macroPoints.get(i)));
351
conic.setPointsOnConic(points);
355
* Makes sure that the start points of locateable are
356
* in its construction.
358
private void initLocateable(Locateable macroLocateable, Locateable locateable) {
359
GeoPoint [] macroStartPoints = macroLocateable.getStartPoints();
360
if (macroStartPoints == null) return;
363
for (int i=0; i < macroStartPoints.length; i++) {
364
GeoPoint point = (GeoPoint) getAlgoGeo(macroStartPoints[i]);
365
locateable.initStartPoint(point, i);
367
//Application.debug("set start point: " + locateable + " => " + point + "(" + point.cons +")");
370
} catch (Exception e) {
371
Application.debug("AlgoMacro.initLocateable:\n" + e.getStackTrace());
376
* Makes sure that the points and segments of poly are
377
* in its construction.
379
private void initPolygon(GeoPolygon macroPoly, GeoPolygon poly) {
381
GeoPoint [] macroPolyPoints = macroPoly.getPoints();
382
GeoPoint [] polyPoints = new GeoPoint[macroPolyPoints.length];
383
for (int i=0; i < macroPolyPoints.length; i++) {
384
polyPoints[i] = (GeoPoint) getAlgoGeo( macroPolyPoints[i] );
386
poly.setPoints(polyPoints);
390
// GeoSegment [] macroPolySegments = macroPoly.getSegments();
391
// GeoSegment [] polySegments = new GeoSegment[macroPolySegments.length];
392
// for (int i=0; i < macroPolySegments.length; i++) {
393
// polySegments[i] = (GeoSegment) getAlgoGeo( macroPolySegments[i] );
394
// initLine(macroPolySegments[i], polySegments[i]);
396
// poly.setSegments(polySegments);
402
* Makes sure that all referenced GeoElements of geoList are
403
* in its construction.
405
final public void initList(GeoList macroList, GeoList geoList) {
406
// make sure all referenced GeoElements are from the algo-construction
408
int size = macroList.size();
410
geoList.ensureCapacity(size);
411
for (int i=0; i < size; i++) {
412
geoList.add( getAlgoGeo(macroList.get(i)) );
417
* Makes sure that all referenced GeoElements of fun are
418
* in this algorithm's construction.
420
final public void initFunction(Function fun) {
421
// geoFun was created as a copy of macroFun,
422
// make sure all referenced GeoElements are from the algo-construction
423
replaceReferencedMacroObjects(fun.getExpression());
427
* Replaces all references to macroGeos in expression exp by references to the corresponding
430
private void replaceReferencedMacroObjects(ExpressionNode exp) {
431
ExpressionValue left = exp.getLeft();
432
ExpressionValue right = exp.getRight();
435
if (left.isGeoElement()) {
436
GeoElement referencedGeo = (GeoElement) left;
437
if (macro.isInMacroConstruction(referencedGeo)) {
438
exp.setLeft(getAlgoGeo(referencedGeo));
441
else if (left.isExpressionNode()) {
442
replaceReferencedMacroObjects((ExpressionNode) left);
448
else if (right.isGeoElement()) {
449
GeoElement referencedGeo = (GeoElement) right;
450
if (macro.isInMacroConstruction(referencedGeo)) {
451
exp.setRight(getAlgoGeo(referencedGeo));
454
else if (right.isExpressionNode()) {
455
replaceReferencedMacroObjects((ExpressionNode) right);
2
GeoGebra - Dynamic Mathematics for Everyone
3
http://www.geogebra.org
5
This file is part of GeoGebra.
7
This program is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by
9
the Free Software Foundation.
13
package geogebra.kernel;
15
import geogebra.euclidian.EuclidianView;
16
import geogebra.kernel.arithmetic.ExpressionNode;
17
import geogebra.kernel.arithmetic.ExpressionValue;
18
import geogebra.kernel.arithmetic.FunctionNVar;
19
import geogebra.kernel.kernelND.GeoPointND;
20
import geogebra.main.Application;
22
import java.util.ArrayList;
23
import java.util.HashMap;
27
* Algorithm to invoke a specific macro.
32
public class AlgoMacro extends AlgoElement
33
implements EuclidianViewCE {
35
private static final long serialVersionUID = 1L;
39
// macro construction, its input and output used by this algo
40
private GeoElement [] macroInput, macroOutput;
42
// maps macro geos to algo geos
43
private HashMap<GeoElement,GeoElement> macroToAlgoMap;
45
// all keys of macroToAlgoMap that are not part of macroInput
46
private ArrayList<GeoElement> macroOutputAndReferencedGeos;
47
private ArrayList<GeoElement> algoOutputAndReferencedGeos; // for efficiency, see getMacroConstructionState()
50
* Creates a new algorithm that applies a macro to the
51
* given input objects.
57
public AlgoMacro(Construction cons, String [] labels, Macro macro, GeoElement [] input) {
63
this.macroInput = macro.getMacroInput();
64
this.macroOutput = macro.getMacroOutput();
66
// register algorithm with macro
67
macro.registerAlgorithm(this);
69
// create copies for the output objects
70
createOutputObjects();
72
// initialize the mapping between macro geos and algo geos
78
// check if macro construction has euclidianAlgos
79
if (macro.getMacroConstruction().hasEuclidianViewCE()) {
80
cons.registerEuclidianViewCE(this);
83
GeoElement.setLabels(labels, getOutput());
85
//we hide objects that are hidden in macro construction, but
86
//we want to do this only with 4.0 macros
87
if(macro.isCopyCaptionsAndVisibility()){
88
for(int i=0;i<macroOutput.length;i++)
89
if(!macroOutput[i].isEuclidianVisible()){
90
getOutput(i).setEuclidianVisible(false);
91
getOutput(i).update();
96
public void remove() {
97
macro.unregisterAlgorithm(this);
101
public String getClassName() {
105
public String getCommandName() {
106
return macro.getCommandName();
109
protected void setInputOutput() {
113
final protected void compute() {
115
// set macro geos to algo geos state
116
setMacroConstructionState();
118
// update all algorithms of macro-construction
119
macro.getMacroConstruction().updateAllAlgorithms();
121
// set algo geos to macro geos state
122
getMacroConstructionState();
124
} catch (Exception e) {
125
Application.debug("AlgoMacro compute():\n");
127
for (int i=0; i < getOutputLength(); i++) {
128
getOutput(i).setUndefined();
133
final public String toString() {
134
return getCommandDescription();
138
* Returns true when macroGeo is part of macroInput.
140
private boolean isMacroInputObject(GeoElement macroGeo) {
141
for (int i=0; i < macroInput.length; i++) {
142
if (macroGeo == macroInput[i])
150
* Sets macro geos to the current state of algo geos.
151
* Start points of vectors should not be copied.
153
final void setMacroConstructionState() {
154
// set input objects of macro construction
155
for (int i=0; i < macroInput.length; i++) {
156
macroInput[i].set(input[i]);
158
if(macroInput[i]instanceof GeoVector)((GeoVector)macroInput[i]).setStartPoint(null);
160
Application.debug("Exception while handling vector input: "+e);
162
macroInput[i].setRealLabel(input[i].label);
163
//Application.debug("SET INPUT object: " + input[i] + " => " + macroInput[i]);
169
* Sets algo geos to the current state of macro geos.
171
final void getMacroConstructionState() {
172
// for efficiency: instead of lookups in macroToAlgoMap
173
// we use an array list algoOutputAndReferencedGeos with corresponding macro and algo geos
174
int size = macroOutputAndReferencedGeos.size();
175
for (int i=0; i < size; i++) {
176
GeoElement macroGeo = (GeoElement) macroOutputAndReferencedGeos.get(i);
177
GeoElement algoGeo = (GeoElement) algoOutputAndReferencedGeos.get(i);
178
if(macroGeo.isDefined()){
179
algoGeo.set(macroGeo);
180
AlgoElement drawAlgo = macroGeo.getParentAlgorithm();
181
if(drawAlgo instanceof AlgoDrawInformation){
182
((GeoNumeric) algoGeo).setDrawable(true);
183
algoGeo.setDrawAlgorithm(((AlgoDrawInformation)drawAlgo).copy());
187
else algoGeo.setUndefined();
193
* Creates the output objects of this macro algorithm
195
private void createOutputObjects() {
196
setOutputLength(macroOutput.length);
197
EuclidianView ev = app.getEuclidianView();
198
int layer = ev == null ? 0 :ev.getMaxLayerUsed();
199
for (int i=0; i < macroOutput.length; i++) {
200
// copy output object of macro and make the copy part of this construction
201
setOutput(i,macroOutput[i].copyInternal(cons));
202
GeoElement out = getOutput(i);
203
out.setUseVisualDefaults(false);
204
out.setAdvancedVisualStyle(macroOutput[i]);
205
if(macro.isCopyCaptionsAndVisibility()){
206
out.setCaption(macroOutput[i].getCaptionNoReplace());
209
AlgoElement drawAlgo = macroOutput[i].getParentAlgorithm();
210
if(drawAlgo instanceof AlgoDrawInformation){
211
((GeoNumeric) out).setDrawable(true);
212
out.setDrawAlgorithm(((AlgoDrawInformation)drawAlgo).copy());
215
out.setAlgoMacroOutput(true);
220
* Inits the mapping of macro geos to algo geos construction.
221
* The map is used to set and get the state of the macro construction in compute()
222
* and to make sure that all output geos of the algorithm and all
223
* their references (e.g. the start point of a ray) are part of the algorithm's
226
private void initMap() {
227
macroToAlgoMap = new HashMap<GeoElement,GeoElement>();
228
macroOutputAndReferencedGeos = new ArrayList<GeoElement>();
229
algoOutputAndReferencedGeos = new ArrayList<GeoElement>();
232
// map macro input to algo input
233
for (int i=0; i < macroInput.length; i++) {
234
map(macroInput[i], input[i]);
238
// map macro output to algo output
239
for (int i=0; i < macroOutput.length; i++) {
240
map(macroOutput[i], getOutput(i));
242
// SPECIAL REFERENCES of output
243
// make sure all algo-output objects reference objects in their own construction
244
// note: we do this in an extra loop to make sure we don't create output objects twice
245
for (int i=0; i < macroOutput.length; i++) {
246
initSpecialReferences(macroOutput[i], getOutput(i));
251
* Adds a (macroGeo, algoGeo) pair to the map.
253
private void map(GeoElement macroGeo, GeoElement algoGeo) {
254
if (macroToAlgoMap.get(macroGeo) == null) {
255
// map macroGeo to algoGeo
256
macroToAlgoMap.put(macroGeo, algoGeo);
258
if (!isMacroInputObject(macroGeo)) {
259
macroOutputAndReferencedGeos.add(macroGeo);
260
// for efficiency: to avoid lookups in macroToAlgoMap
261
algoOutputAndReferencedGeos.add(algoGeo);
267
* Returns a GeoElement in this algo's construction
268
* that corresponds to the given macroGeo from the macro construction.
269
* If a macro-geo is not yet
270
* mapped to an algo-geo, a new algo-geo is created and added to
271
* the map automatically.
273
private GeoElement getAlgoGeo(GeoElement macroGeo) {
274
if (macroGeo == null) return null;
275
GeoElement algoGeo = (GeoElement) macroToAlgoMap.get(macroGeo);
277
// if we don't have a corresponding GeoElement in our map yet,
278
// create a new geo and update the map
279
if (algoGeo == null) {
280
algoGeo = createAlgoCopy(macroGeo);
281
map(macroGeo, algoGeo);
288
* Creates a new algo-geo in this construction that is copy of macroGeo from
289
* the macro construction.
291
private GeoElement createAlgoCopy(GeoElement macroGeo) {
292
GeoElement algoGeo = macroGeo.copyInternal(cons);
298
* Some GeoElement types need special settings as they reference other
299
* GeoElement objects. We need to make sure that algoGeo
300
* only reference objects in its own construction.
302
private void initSpecialReferences(GeoElement macroGeo, GeoElement algoGeo) {
304
switch (macroGeo.getGeoClassType()) {
305
case GeoElement.GEO_CLASS_INTERVAL:
306
case GeoElement.GEO_CLASS_FUNCTION:
307
initFunction(((GeoFunction) algoGeo).getFunction());
310
case GeoElement.GEO_CLASS_FUNCTIONCONDITIONAL:
311
// done by set() in GeoFunctionConditional
312
// actually a GeoFunctionConditional consists of three GeoFunction objects,
313
// so initFunction() is eventually used for them
316
case GeoElement.GEO_CLASS_LIST:
317
initList((GeoList) macroGeo, (GeoList) algoGeo);
320
case GeoElement.GEO_CLASS_LINE:
321
case GeoElement.GEO_CLASS_LINEAR_INEQUALITY:
322
initLine((GeoLine) macroGeo, (GeoLine) algoGeo);
325
case GeoElement.GEO_CLASS_POLYGON:
326
initPolygon((GeoPolygon) macroGeo, (GeoPolygon) algoGeo);
329
case GeoElement.GEO_CLASS_CONIC:
330
initConic((GeoConic) macroGeo, (GeoConic) algoGeo);
333
case GeoElement.GEO_CLASS_TEXT:
334
case GeoElement.GEO_CLASS_VECTOR:
335
case GeoElement.GEO_CLASS_IMAGE:
336
initLocateable((Locateable) macroGeo, (Locateable) algoGeo);
340
// no special treatment necessary at the moment
341
// case GeoElement.GEO_CLASS_ANGLE:
342
// case GeoElement.GEO_CLASS_BOOLEAN:
343
// case GeoElement.GEO_CLASS_CONICPART:
344
// case GeoElement.GEO_CLASS_LOCUS:
345
// case GeoElement.GEO_CLASS_NUMERIC:
346
// case GeoElement.GEO_CLASS_POINT:
347
// case GeoElement.GEO_CLASS_AXIS:
348
// case GeoElement.GEO_CLASS_RAY:
349
// case GeoElement.GEO_CLASS_SEGMENT:
350
// case GeoElement.GEO_CLASS_POLYGON:
355
* Makes sure that the start and end point of a line are
356
* in its construction (if the line has this kind of information).
358
private void initLine(GeoLine macroLine, GeoLine line) {
359
GeoPoint startPoint = (GeoPoint) getAlgoGeo(macroLine.getStartPoint());
360
GeoPoint endPoint = (GeoPoint) getAlgoGeo(macroLine.getEndPoint());
361
line.setStartPoint(startPoint);
362
line.setEndPoint(endPoint);
366
* Makes sure that all points on conic are
367
* in its construction.
369
private void initConic(GeoConic macroConic, GeoConic conic) {
370
ArrayList<GeoPoint> macroPoints = macroConic.getPointsOnConic();
371
if (macroPoints == null) return;
373
int size = macroPoints.size();
374
ArrayList<GeoPoint> points = new ArrayList<GeoPoint>(size);
375
for (int i=0; i < size; i++) {
376
points.add((GeoPoint)getAlgoGeo(macroPoints.get(i)));
378
conic.setPointsOnConic(points);
382
* Makes sure that the start points of locateable are
383
* in its construction.
385
private void initLocateable(Locateable macroLocateable, Locateable locateable) {
386
GeoPoint [] macroStartPoints = (GeoPoint[]) macroLocateable.getStartPoints();
387
if (macroStartPoints == null) return;
390
for (int i=0; i < macroStartPoints.length; i++) {
391
GeoPoint point = (GeoPoint) getAlgoGeo(macroStartPoints[i]);
392
locateable.initStartPoint(point, i);
394
//Application.debug("set start point: " + locateable + " => " + point + "(" + point.cons +")");
397
} catch (Exception e) {
398
Application.debug("AlgoMacro.initLocateable:\n" + e.getStackTrace());
403
* Makes sure that the points and segments of poly are
404
* in its construction.
406
private void initPolygon(GeoPolygon macroPoly, GeoPolygon poly) {
408
GeoPointND [] macroPolyPoints = macroPoly.getPoints();
409
GeoPoint [] polyPoints = new GeoPoint[macroPolyPoints.length];
410
for (int i=0; i < macroPolyPoints.length; i++) {
411
polyPoints[i] = (GeoPoint) getAlgoGeo( (GeoElement) macroPolyPoints[i] );
413
poly.setPoints(polyPoints);
417
// GeoSegment [] macroPolySegments = macroPoly.getSegments();
418
// GeoSegment [] polySegments = new GeoSegment[macroPolySegments.length];
419
// for (int i=0; i < macroPolySegments.length; i++) {
420
// polySegments[i] = (GeoSegment) getAlgoGeo( macroPolySegments[i] );
421
// initLine(macroPolySegments[i], polySegments[i]);
423
// poly.setSegments(polySegments);
429
* Makes sure that all referenced GeoElements of geoList are
430
* in its construction.
431
* @param macroList GeoList of macro geos
432
* @param geoList GeoList of construction geos
434
final public void initList(GeoList macroList, GeoList geoList) {
435
// make sure all referenced GeoElements are from the algo-construction
437
int size = macroList.size();
439
geoList.ensureCapacity(size);
440
for (int i=0; i < size; i++) {
441
geoList.add( getAlgoGeo(macroList.get(i)) );
447
* Makes sure that all referenced GeoElements of fun are
448
* in this algorithm's construction.
451
final public void initFunction(FunctionNVar fun) {
452
// geoFun was created as a copy of macroFun,
453
// make sure all referenced GeoElements are from the algo-construction
454
replaceReferencedMacroObjects(fun.getExpression());
458
* Replaces all references to macroGeos in expression exp by references to the corresponding
461
private void replaceReferencedMacroObjects(ExpressionNode exp) {
462
ExpressionValue left = exp.getLeft();
463
ExpressionValue right = exp.getRight();
466
if (left.isGeoElement()) {
467
GeoElement referencedGeo = (GeoElement) left;
468
if (macro.isInMacroConstruction(referencedGeo)) {
469
exp.setLeft(getAlgoGeo(referencedGeo));
472
else if (left.isExpressionNode()) {
473
replaceReferencedMacroObjects((ExpressionNode) left);
479
else if (right.isGeoElement()) {
480
GeoElement referencedGeo = (GeoElement) right;
481
if (macro.isInMacroConstruction(referencedGeo)) {
482
exp.setRight(getAlgoGeo(referencedGeo));
485
else if (right.isExpressionNode()) {
486
replaceReferencedMacroObjects((ExpressionNode) right);