## -*-octave-*- function [bonds] = ... rbg2ibg(name,rbonds,rstrokes,rcomponents,port_coord,port_name, ... infofile, errorfile) rbonds rstrokes rcomponents port_coord port_name ## Default to no components components = [0]; ## Xfig scaling factor scale = 1200.0/2.54546; ## Rotation matrix rot = [0, -1; 1, 0]; ## Find number of strokes [n_strokes,columns] = size(rstrokes); if ((columns ~= 4) & (n_strokes > 0)) error('Incorrect rstrokes matrix: must have 4 columns'); endif ## Find number of bonds [n_bonds,columns] = size(rbonds); if ((columns ~= 6) & (n_bonds > 0)) error('Incorrect rbonds matrix: must have 6 columns'); endif ## Find number of components [n_components,columns] = size(rcomponents); ## Find number of ports referred to [n_ports,columns] = size(port_coord); ## If port_name empty, make it empty string if (length(port_name) == 0) port_name=""; endif ## Determine coordinates of arrow end of bond and other end other_end_1 = rbonds(:,1:2); arrow_end = rbonds(:,3:4); other_end_2 = rbonds(:,5:6); distance_1 = length2d(other_end_1 - arrow_end); distance_2 = length2d(other_end_2 - arrow_end); which_end = (distance_1 > distance_2) * [1, 1]; one = ones(size(which_end)); other_end = which_end .* other_end_1 + (one - which_end) .* ... other_end_2; arrow_vector = (which_end .* other_end_2 + (one - which_end) .* ... other_end_1) - arrow_end; ## Locate bond end nearest each port ## col 1 of port_near_bond contains a signed bond number (+ for arrow ## end) ## col 2 of port_near_bond contains the corresponding port index port_bond = []; for i = 1:n_ports near_bond = adjbond(port_coord(i,1:2), arrow_end, other_end); [rows,cols] = size(near_bond); if (rows > 1) error(sprintf ... ("A port is near to more than one bond at coordinates ... %g,%g %s\n", ... port_coord(i,1)/scale, port_coord(i,2)/scale, ... deblank(port_name(i,:)))); endif ## The (signed) bond corresponding to the ith port label port_bond(i,1) = near_bond(1) * sign(1.5 - near_bond(2)); endfor port_bond ## Now have (signed) bond (port_bond(i)) corresponding to the ith port ## Create inverse mapping for i = 1:n_bonds eval(sprintf('bond_port_head%i = "[]"', i)) eval(sprintf('bond_port_tail%i = "[]"', i)) endfor for i = 1:n_ports if (port_bond(i) > 0) eval(sprintf('bond_port_head%i = "%s"', port_bond(i), ... deblank(port_name(i,:)))) else eval(sprintf('bond_port_tail%i = "%s"', -port_bond(i), ... deblank(port_name(i,:)))) endif endfor ## Locate the components at the ends of each bond ## col 1 of comp_near_bond contains component nearest to the arrow end ## col 2 of comp_near_bond contains component nearest other end for i = 1:n_bonds comp_near_bond(i,:) = adjcomp(arrow_end(i,:), other_end(i,:), ... rcomponents); endfor comp_near_bond ## Deduce causality from the strokes (if any) causality = zeros(n_bonds,2); if (n_strokes > 0) ## Find location of centre and ends of stroke stroke_end_1 = [rstrokes(:,1), rstrokes(:,2)]; stroke_end_2 = [rstrokes(:,3), rstrokes(:,4)]; stroke_centre = (stroke_end_1 + stroke_end_2)/2; stroke_vector = (stroke_end_1 - stroke_end_2); stroke_length = length2d(stroke_vector); for i = 1:n_strokes stroke = [stroke_centre(i,:) stroke_end_1(i,:) stroke_end_2(i,:)]; ## Find the nearest bond end [index,distance] = adjbond(stroke(1,:),arrow_end,other_end); if (distance > (2 * stroke_length(i))) info = sprintf('Stroke at (%4.3f,%4.3f) is %4.3f away from the nearest bond\n', ... stroke(1,1)/scale, stroke(1,2)/scale, ... distance/scale); endif ## Bond end coordinates j = index(1,1); which_end = (index(1,2) == 1); bond_end = arrow_end(j,:) * which_end + other_end(j,:) * (1 - ... which_end); ## Now decide which bit of the stroke is nearest stroke_index = adjbond(bond_end, stroke, zeros(size(stroke))); if (stroke_index(1) == 1) # uni-causal stroke causality(j,1:2) = (2 * which_end - 1) * [1, 1]; else # bi-causal stroke stroke_direction = stroke(1,:) - stroke(stroke_index(1),:); flow_side = stroke_direction * arrow_vector(j,:)' > 0; causality(j,1+flow_side) = 2 * which_end - 1; endif endfor endif causality ## Write data for i = 1:n_bonds [hc_type, hc_name] = eval([name, '_cmp(comp_near_bond(i,1))']); [tc_type, tc_name] = eval([name, '_cmp(comp_near_bond(i,2))']); ## components eval(sprintf("bonds.bond%i.head.component\t= '%s:%s'", i, hc_type, ... hc_name)); eval(sprintf("bonds.bond%i.tail.component\t= '%s:%s'", i, tc_type, ... tc_name)); ## ports eval(sprintf("bonds.bond%i.head.ports\t= bond_port_head%i", i, i)); eval(sprintf("bonds.bond%i.tail.ports\t= bond_port_tail%i", i, i)); ## causality if (causality(i,1) == 1) effort_causality = "head" elseif (causality(i,1) == -1) effort_causality = "tail" else effort_causality = "none" endif if (causality(i,2) == 1) flow_causality = "tail" elseif (causality(i,2) == -1) flow_causality = "head" else flow_causality = "none" endif eval(sprintf("bonds.bond%i.causality.effort\t= '%s'", i, effort_causality)); eval(sprintf("bonds.bond%i.causality.flow\t= '%s'", i, flow_causality)); endfor endfunction