5
$\begingroup$

I am 100% new to mathematica and I don't really understand if I am doing this correctly. I have some most code except the calculation of the color. I will do that once I know I am doing this correctly. I am trying to make sure it is correct and if am not I need some direction as to what I am doing wrong. I added comments if that helps. Anything helps!

(* Triangle vertices *)

v1 = {-2.0, -2.0};
v2 = {2.0, -2.0};
v3 = {0.0, 2.0};

(* xy-space to plot *)

c1 = {1, 0, 0};
c2 = {0, 1, 0};
c3 = {0, 0, 1};   

I am trying to Compute the barycentric coordiantes of a 2D point xy based on triangle vertices v1, v2, v3 and that is what I need help on because I'm not sure that I got it right.

(* Input: xy = {x, y} and global v1, v2, v2 each as {x,y} *)
(* Output: uvw = {u, v, w}, the barycentric coordinates *)


(* The entries in the linear system set-up below need set. I Determine what  
   values in function *)

computeBaryCoords[xy_] := (
  mat = {{v1[[1]], v2[[1]], v3[[1]]}, {v1[[2]], v2[[2]], v3[[2]]}, {v1, v2, v3}};
  rhs = {xy[[1]], xy[[2]], mat};
  uvw = LinearSolve[mat, rhs];
  Return[uvw]
  );

computeColor[uvw_] := Return[ (* going to calculate colors *)]; 

range = 4;
plotTriangle = 
  Graphics[
    {EdgeForm[Thick], White, Polygon[{v1, v2, v3}], 
     PointSize[0.05], 
     RGBColor[c1], Point[v1], 
     RGBColor[c2], Point[v2], 
     RGBColor[c3], Point[v3]}, 
    Axes -> True, 
    PlotRange -> {{-range, range}, {-range, range}}];

Manipulate[(
  uvw = computeBaryCoords[xy];
  rgb = computeColor[uvw];
  plotPoint = 
    Graphics[
      {RGBColor[rgb[[1]], rgb[[2]], rgb[[3]]], PointSize[0.08],  Point[xy]}];
  plotBaryCoords =  
    Graphics[
      {Black 
       Text[Style["Barycentric Coordinates: ", FontSize -> 15], {0, 4}, Scaled[{1, 1}]], 
       Text[Style[NumberForm[uvw, 2], FontSize -> 15], {4, 4}, Scaled[{1, 1}]]}];
  Show[{plotTriangle, plotPoint, plotBaryCoords}]),
  {{xy, {0, 0}}, Locator}]
$\endgroup$
  • $\begingroup$ Does computeBaryCoords work incorrectly? Or is it the Manipulate that misbehaves? $\endgroup$ – Michael E2 Sep 29 '17 at 1:26
  • $\begingroup$ @michaelE2 I had to respost the question becuase I posted as guest and I could not comment on it. Yes I think the problem is in the computerBaryCords $\endgroup$ – user2896245 Sep 29 '17 at 1:39
  • $\begingroup$ Please go here to have your accounts merged and regain access to your question. $\endgroup$ – J. M. will be back soon Sep 29 '17 at 1:43
5
$\begingroup$

I tweaked your function slightly:

computeBaryCoords[xy_] := With[
    {mat = {{v1[[1]], v2[[1]], v3[[1]]}, {v1[[2]], v2[[2]], v3[[2]]}, {1, 1, 1}}},
    LinearSolve[mat, Append[xy, 1]]
]

Basically, your mat and rhs were not quite right, and one should never use Return as the last expression, as it is redundant. Quick check:

coords = computeBaryCoords[{1,1}]
coords . {v1, v2, v3}

{-0.125, 0.375, 0.75}

{1., 1.}

However, I think it makes sense to make the dependencies on the vertices explicit, so I would use something like this:

BarycentricTransform[{v1_,v2_,v3_}] := TransformationFunction[
    PadRight[
        Inverse @ PadRight[Transpose@{v1,v2,v3}, {3,3}, 1],
        {4,3},
        {{0,0,1}}
    ]
]

Here is an example of it in use:

bf = BarycentricTransform[{v1, v2, v3}];

bf[{{1,1}, {1,2}, {0, 1}}]
% . {v1,v2,v3}

{{-0.125, 0.375, 0.75}, {-0.25, 0.25, 1.}, {0.125, 0.125, 0.75}}

{{1., 1.}, {1., 2.}, {0., 1.}}

Update

Here's an update that works with higher dimensions:

BarycentricTransform::nonn1 = "The list of vectors should have equal length, and the number of arguments is expected to be 1 less than their length";

BarycentricTransform[v_List] := Module[{dim=Dimensions[v], res},
    res = If[!MatchQ[dim, {n_, m_} /; m+1 == n], 
        Message[BarycentricTransform::nonn1];
        $Failed,

        With[{mat = Inverse @ PadRight[Transpose @ v, dim + {0, 1}, 1]},
            AffineTransform[{mat[[All, ;;-2]], mat[[All, -1]]}]
        ]
    ];
    res /; !MatchQ[res, $Failed | _AffineTransform]
]

An example with dimension 5:

SeedRandom[1];
v = RandomReal[10, {5, 4}];
bf = BarycentricTransform[v];

pts = RandomReal[5, {3, 4}];
bf[pts]

{{5.93009, -0.958983, 4.6546, -3.60732, -5.01838}, {-1.13559, 1.21887, -0.129826, 0.174377, 0.872176}, {4.93582, -0.689189, 3.94031, -2.94722, -4.23972}}

Check that the coordinates sum to 1:

Total[bf[pts], {2}]

{1., 1., 1.}

Check that the dot product with the vectors reproduces the initial points:

bf[pts] . v == pts

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.